javascript - 状态变化未反映在 Next.Js 中的功能中
问题描述
我有一个渲染出一系列产品的功能组件。我从它的道具中得到了一系列产品,并设置了它的状态使用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
. 在某些有限的情况下,在非常昂贵的情况下运行回调时,进行记忆化回调可能会有所帮助。但是您必须非常小心以确保您的依赖项列表是正确的。
在您的实例中,没有理由记住handleQueryValueChange
and handleTaggedWithChange
,这些可能会导致您的问题。它们既没有依赖items
也originalItems
没有依赖,因此它们没有得到更新。
真正重要的部分是过度使用 memoization 意味着这些函数引用了旧的副本handleFiltering
,该副本存在于originalItems
仍然是空数组的范围/上下文中。
摆脱所有useCallback
s 可能是最好的方法......handleFiltering
如果您开始遇到性能问题并且发现 memoization 有帮助,您可以随时将其添加回来。
推荐阅读
- python - 赛马模拟器
- r - 根据选择的选项过滤 R 中的 2 个表格并在闪亮的应用程序中显示图表
- c++ - 释放对象的校验和不正确 - 分配问题
- ms-word - 如何用超链接运行替换 Apache POI for Word 中的 XWPFRun?
- php - 尝试使用 Xenforo 创建资源线程时出错
- javascript - 我没有在 html 中显示 ajax 表,为什么?
- excel - 如何显示一个确认弹出窗口,允许使用宏编辑 Excel 文件的任何单元格中存在的特定文本?
- reactjs - Web API 请求被重定向到 index.html
- reactjs - 从 MaterialUI v4 升级到 MaterialUI v5 后 - 缺少默认主题导致挂载测试失败。如何恢复默认主题?
- java - Java 11 - 以捷克克朗 ####,## Kč 格式显示小数