【发布时间】:2021-09-18 02:13:13
【问题描述】:
我有一个功能组件,它呈现出一系列产品。我从它的道具中获取产品数组,并使用useEffect 和useState 钩子设置它的状态。
我正在尝试通过获取原始数组和 根据某些条件对其进行过滤。
此组件会重新渲染几次,因为它是从父级中的 ajax 调用加载的项目。这里的问题是,即使originalItems 的值最终会更新,这并不能反映何时调用handleFiltering 方法。在这个方法中,originalItems 的值仍然是一个空数组。
有人能解释一下为什么这个变量的状态没有在这个函数中更新吗?有没有办法解决这个问题?提前致谢!
代码如下:
const ProductList = ({ items }) => {
const [taggedWith, setTaggedWith] = useState("");
const [queryValue, setQueryValue] = useState("");
const [originalItems, setOriginalItems] = useState([]);
const [filteredItems, setFilteredItems] = useState([]);
useEffect(() => {
setOriginalItems(items);
setFilteredItems(items);
}, [items]);
const handleQueryValueChange = useCallback(
(value) => {
setQueryValue(value);
handleFiltering(value, taggedWith);
},
[taggedWith, handleFiltering]
);
const handleTaggedWithChange = useCallback(
(value) => {
setTaggedWith(value);
handleFiltering(queryValue, value);
},
[queryValue, handleFiltering]
);
// PROBLEM HERE
const handleFiltering = useCallback(
(filter, tag) => {
// originalItems is still an empty array here. So as a result, the filteredValues
array is always empty.
const filtered = originalItems.filter((item) => {
if ((!filter || item.title.toLowerCase().includes(filter.toLowerCase())) && (!tag ||
item.tags.includes(tag))) return item;
});
setFilteredItems(filtered);
},
[originalItems]
);
return (
<Page >
<Card>
<ResourceList
items={filteredItems}
loading={loading}
/>
</Card>
</Page>
);
};
export default ProductList;
(请注意,我省略了一些代码以减少混乱。taggedWith 和 queryValue 的值已正确更新,但我省略了那段代码)
【问题讨论】:
-
也许在没有所有记忆回调的情况下尝试一下?当然你不需要记住前两个,我猜你也不需要记住第三个。您应该能够在没有
useCallback的情况下定义普通的旧箭头函数。 -
@David784 非常感谢!这似乎解决了这个问题!我确实尝试在没有
useCallback的情况下单独使用handleFiltering函数,但这并没有解决问题。没有记住所有内容似乎已经解决了这个问题。
标签: javascript reactjs react-hooks next.js use-state