[英]How do I use React state in combination with a dynamic filter component?
I have a filter component that filters a set of data.我有一个过滤器组件来过滤一组数据。 I want to output the filtered data to the DOM by using the filtered object in the local state.
我想通过在本地 state 中使用过滤后的 object 将过滤后的数据 output 到 DOM。 I cannot figure out how to use state without reseting the filter input and I can also not figure out how to output the filtered data to the DOM without using state.
我无法弄清楚如何在不重置过滤器输入的情况下使用 state,我也无法弄清楚如何在不使用 state 的情况下将过滤后的数据 output 到 DOM。
This is the dataset:这是数据集:
const data = [
{ Name: John,
Tags: [walking, senior, Amsterdam]
},
{Name: Chris,
Tags: [biking, junior, The Hague]
},
{Name: Marc,
Tags: [walking, junior, Amsterdam]
}
I want to filter this dataset based on the tags the client selects:我想根据客户选择的标签过滤这个数据集:
<select data-categorie={hobby} onChange={filterTagHandler}>
<option value='all'>All><option>
<option value='walking'>Walking><option>
<option value='biking'>Biking><option>
<select>
<select data-categorie={age} onChange={filterTagHandler}>
<option value='all'>All><option>
<option value='junior'>Junior><option>
<option value='senior'>Senior><option>
<select>
<select data-categorie={city} onChange={filterTagHandler}>
<option value='all'>All><option>
<option value='amsterdam'>Amsterdam><option>
<option value='the hague'>The Hague><option>
<select>
The filter select components are dynamically generated from client input.过滤器 select 组件是从客户端输入动态生成的。 Therefor there is just the filterTagHandler instead of a nameHandler, hobbyHandler, cityHandler.
因此只有 filterTagHandler 而不是 nameHandler、hobbyHandler、cityHandler。
First thing is to handle the selected tags and create an array from the selected tags:首先是处理选定的标签并从选定的标签创建一个数组:
const selectedTagsArray = []
const filterTagHandler = (e) => {
const option = e.target.options
const tagSelected = option[option.selectedIndex].value
const categorie = e.target.dataset.categorie
selectedTagsArray.push(tagSelected)
// Handle new option in categorie
handleNewOptionInCategorie(categorie, tagSelected)
// Handle all option
handleAllOption(tagSelected)
// Filter items
filterItems(selectedTagsArray)
}
So the first thing that happens in this onChange function is the selected tag is push to the selectedTagsArray.所以在这个 onChange function 中发生的第一件事就是选择的标签被推送到 selectedTagsArray。 If I would set the selectedTagsArray to state:
如果我将 selectedTagsArray 设置为 state:
const [tagsArray, setTagsArray] = useState([])
setTagsArray(selectedTagsArray)
the selectedTagsArray would be emptied every time the client selects a new filter option, because the state get's updated.每次客户端选择新的过滤器选项时, selectedTagsArray 都会被清空,因为 state 已更新。 So that's no good.
所以这不好。
So first I use some logic to update the selectTagsArray if the client selects a new option within a categorie (select component):因此,如果客户端在类别中选择新选项(选择组件),首先我使用一些逻辑来更新 selectTagsArray:
const handleNewOptionInCategorie = (categorie, tagSelected) => {
filterTags && filterTags[categorie].forEach((tag) => {
if(selectedTagsArray.includes(tag.Tag) && tag.Tag !== tagSelected){
const index = selectedTagsArray.indexOf(tag.Tag)
selectedTagsArray.splice(index, 1)
}
})
}
Then I handle the 'All' option:然后我处理“全部”选项:
const handleAllOption = (tagSelected) => {
if(tagSelected === 'All'){
const index = selectedTagsArray.indexOf(tagSelected)
selectedTagsArray.splice(index, 1)
}
}
This all works fine (as long as there is no state change along the way).这一切都很好(只要一路上没有 state 变化)。
Next I filter the data based on the selected tags:接下来我根据选定的标签过滤数据:
const filterItems = (array) => { const filterItems = (array) => {
const newArray = []
data.forEach(item => {
if(array.every(tag => item.Tags.includes(tag))){
newArray.push(item)
}
})
}
So this gives me the filtered data in the newArray object.所以这给了我 newArray object 中的过滤数据。 The next logical step now would be to:
现在的下一个合乎逻辑的步骤是:
const [filteredItems, setFilteredItems] = useState(data)
setFilteredItems(newArray)
This has to be done inside the filteredItems object.这必须在filteredItems object 中完成。
But I cannot use state here as well, since the filterItems function is called inside the filterTaghandler onChange and so every time the client selects a new option the state updates and the selectedTagsArray is emptied.但是我也不能在这里使用 state,因为 filterItems function 在 filterTaghandler onChange 内部被调用,因此每次客户端选择一个新选项时,Z9ED39E2EA931586B76A985A6942EF5
So, how can I use the newArray object to update the DOM or how can I use state without emptying the selectedTagsArray?那么,如何使用 newArray object 来更新 DOM,或者如何在不清空 selectedTagsArray 的情况下使用 state?
I solved it by updating the state with the state.我通过用 state 更新 state 解决了这个问题。 It's a pretty simple solution, but it works.
这是一个非常简单的解决方案,但它确实有效。
So instead of updating the selectedTagsArray if update the state like:因此,如果更新 state ,而不是更新 selectedTagsArray ,例如:
setFilterTags(...filterTags, tagSelected). setFilterTags(...filterTags, tagSelected)。 I'm using an onClick event to filter instead of it being called in the onChange.
我正在使用 onClick 事件进行过滤,而不是在 onChange 中调用它。
I can now use the filterTags state to filter the data and update the data state to update the DOM.我现在可以使用 filterTags state 过滤数据并更新数据 state 来更新 DOM。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.