到目前为止,仅当我键入api中存在的确切名称时,我才可以搜索数组的元素,在这种情况下,我的api具有一个包含20个位置的数组,如果我键入的是我搜索的元素的名称,则返回一个具有19个未定义位置和1个已找到位置的数组的数组,我想在键入时进行搜索,而不是仅在输入全名时进行搜索。 搜索之后,我尝试更改组件的状态,以便仅使用获取的值来呈现该组件,但是如果有人知道我非常感激,则不会发生这种情况。
updated code
import data from "../sample_data/recipes.json";
class App extends Component {
constructor(props) {
super(props);
this.state = {
searchString: []
};
}
componentDidMount() {
this.setState({ searchString: data.results })
}
onChange(fieldName) {
if (fieldName === '' || fieldName === null) this.setState({ searchString: data.results });
var indexes = data.results.filter((item, i) => {
return item.title.toLowerCase().indexOf(fieldName.toLowerCase()) !== -1;
})
this.setState({ searchString : indexes });
}
render() {
return (
<div className="App">
<Navbar onChange={this.onChange.bind(this)} />
<div className="container mt-10">
<div className="row">
{<RecipeItem list={this.state.searchString} />}
</div>
</div>
</div>
);
}
}
export default App;
答案 0 :(得分:0)
setState
移到map
之外。也许试试看?
var indexes = [];
data.results.forEach(item => {
if(item.title.indexOf(myObjTitle.title)) {
indexes.push(item);
}
});
this.setState({searchString : indexes});
答案 1 :(得分:0)
我不确定我是否完全理解您的问题,看来您正在尝试过滤匹配的结果。在这种情况下,最好使用filter
而不是map
。
onChange(fieldName) {
if (fieldName === '' || !fieldName) {
this.setState({ searchString: data.results })
}
const indexes = data.results.filter(item => (
item.title === fieldName
));
this.setState({searchString : indexes});
}
也就是说,如果您希望item.title和fieldName之间完全匹配。如果要查找包含搜索字符串fieldName
的所有结果,则必须使用item.title.indexOf(fieldName) !== -1
而不是item.title === fieldName
。您可以在测试条件下更加微妙,例如为了不区分大小写。
另外,如果您想要单个结果(第一个匹配的结果),则使用find
而不是filter
更好,因为它会在第一个匹配之后停止搜索,而不是遍历整个数组
返回一个新数组,其中的条目数量与以前一样多,但是您可以返回所需的任何内容作为条目,这就是为什么您现在获得这么多undefined
条目的原因。 (因为仅当标题匹配时才返回一个项目,因此在不匹配时隐式返回undefined)。 Map遍历整个数组。
返回一个新数组,其中包含与测试功能匹配的条目。如果函数返回true,则包含该项目,返回false,该项目将被省略。过滤器遍历整个数组。
将仅检索与您的测试功能匹配的第一个条目。一旦找到匹配项,它将停止循环。
您最有可能需要学习有关反跳的知识,您可以使用lodash.debounce进行反跳。
去抖是一种用于防止函数在短时间内执行多次的方法(这样就不必渲染)
答案 2 :(得分:0)
我想您想在键入时进行某种过滤:
您可以试试吗? :
onChange(fieldName) {
if (fieldName === '' || fieldName === null) this.setState({ searchString: data.results });
var filteredItems = data.results.filter((item, i) => {
return item.title.toLowerCase().indexOf(fieldName.toLowerCase()) === -1;
})
this.setState({ searchString : filteredItems });
}
说明:
要求的是不显示包含键入字母的项目,为此,您可以将过滤器项目与filter
方法一起使用,并仅返回标题中没有键入字母的项目(使用indexOf
方法)。
答案 3 :(得分:0)
据我所知,您正在尝试从json Array中搜索元素,我刚刚添加了新键来存储filterString。这是我的解决方法
onChange(firstName){
if(firstName != undefined){
this.setState({
nameToFilter : firstName
})
}
}
//在render方法内部 我正在使用nameToFilter来过滤数据。
render() {
let searchString = this.state.searchString
if(this.state.nameToFilter != undefined && this.state.nameToFilter.length>0)
{
searchString = this.state.searchString.filter(item => (
item.title == this.state.nameToFilter
));
}
return (
<div className="App">
<Navbar onChange={this.onChange.bind(this)} />
<div className="container mt-10">
<div className="row">
{<RecipeItem list={searchString} />}
</div>
</div>
</div>
);
}