我有这个搜索栏功能,可以搜索State州的葡萄酒以缩小范围。键入时,状态更改为“ isLoading === true”,并显示正确的结果一秒钟,但随后返回显示所有结果,而不仅仅是显示输入的参数。我的网站已https://www.winewise.biz/allwines上架,因此您可以对其进行测试。这是搜索栏的代码:
git branch --format '%(refname:lstrip=2)' --merged `
| Where-Object { $_ -ne 'master' } `
| ForEach-Object { git branch -d $_ }
答案 0 :(得分:0)
在我看来,这个问题就像您有2个条件争相设定状态一样。
您在handleSearchChange
期间启动了API请求,该请求设置了状态。每种类型的键盘上发生的一些API请求都在过滤后设置 状态。它可能在localhost上运行良好,因为您有setTimeout时,请求会在应用过滤器(<300毫秒)之前返回。
仅在api请求之后,才应使用promises来控制流和过滤。我还建议您这样做,因为您似乎没有在做任何过滤服务器端的工作,您只发出一次API请求,然后仅在组件状态下进行过滤。
观看“网络”选项卡,您可以看到API调用成功后,状态如何设置为未过滤结果的完整列表。
一些小的更改应该会有所帮助,减去您不应该在每种类型上调用API.getWines()
的事实。
handleSearchChange = (e, { value }) => {
this.setState({ isLoading: true, value });
API.getWines()
.then(res => {
const re = new RegExp(_.escapeRegExp(this.state.value), "i");
//what is being tested for in search input
const isMatch = result => re.test(result.Wine);
this.setState({
wines: _.filter(this.state.wines, isMatch)
})
}
)
.catch(err => console.log(err));
};
答案 1 :(得分:0)
感谢您的帮助。因此,每个人的建议都很有见地,我意识到将所有内容首先放入状态然后进行过滤似乎很直观,但是问题是当有人输入错误并尝试删除时,某些葡萄酒可能会从状态中删除。 >
我所做的只是在状态中设置了另一个变量“ list”,该变量跟踪来自状态的过滤后的葡萄酒。这很棒!
import _ from "lodash";
import React, { Component } from "react";
import { Search} from "semantic-ui-react";
import API from '../../utils/API'
import { Link } from "react-router-dom"
import "./searchwines.css";
export default class SearchBar extends Component {
state = {
wines: [],
list: []
}
componentDidMount() {
this.resetComponent();
API.getWines()
.then(res => {
this.setState({ wines: res.data })
}
)
.catch(err => console.log(err));
}
resetComponent = () =>
this.setState({ isLoading: false, wines: [], value: "" });
//What shows on the results bar when you click on it:
handleResultSelect = (e, { result }) =>
this.setState({ value: result.Wine });
handleSearchChange = (e, { value }) => {
this.setState({ isLoading: true, value });
API.getWines()
.then(res => {
this.setState({ wines: res.data })
}
)
.catch(err => console.log(err));
setTimeout(() => {
if (this.state.value.length < 1) return this.resetComponent();
const re = new RegExp(_.escapeRegExp(this.state.value), "i");
//what is being tested for in search input
const isMatch = result => re.test(result.Wine);
this.setState({
isLoading: false,
list: _.filter(this.state.wines, isMatch)
});
}, 300);
};
render() {
const { isLoading, value, wines, list } = this.state;
const resRender = ({ Wine, Producer, _id }) => (
<Link to={"/details/" + _id}>
<div key="name">
{Wine}, {Producer}
</div>
</Link>
);
return (
<Search
placeholder="Search wines..."
loading={isLoading}
onResultSelect={this.handleResultSelect}
onSearchChange={_.debounce(this.handleSearchChange, 500, {
leading: true
})}
results={list}
value={value}
resultRenderer={resRender}
/>
);
}
}