Javascript 反应-筛选存储中的对象会导致递归/无限循环
我在react应用程序中使用redux store来存储我的开支等数据 现在我在其中一个组件中使用这些费用来计算TODO徽章计数,如下所示Javascript 反应-筛选存储中的对象会导致递归/无限循环,javascript,reactjs,use-effect,Javascript,Reactjs,Use Effect,我在react应用程序中使用redux store来存储我的开支等数据 现在我在其中一个组件中使用这些费用来计算TODO徽章计数,如下所示 const [badgeValue, setBadgeValue] = useState(0); const expenses = useSelector(({ expenses }: RootState) => expenses.items); useEffect(() => { const setBadge = async () =
const [badgeValue, setBadgeValue] = useState(0);
const expenses = useSelector(({ expenses }: RootState) => expenses.items);
useEffect(() => {
const setBadge = async () => {
const badgeNumber = await calculateRequestBadgeNumber(expenses);
setBadgeValue(badgeNumber);
};
setBadge();
return () => setBadgeValue(0);
}, [expenses]);
这正如预期的那样有效。然而现在,当我想过滤掉删除的费用时,我遇到了一个奇怪的副作用,比如:
const expenses = useSelector(({ expenses }: RootState) =>
expenses.items.filter((expense: Expense) => !expense.deleted)
);
这将导致调用useEffects的无休止循环。为什么会发生这种情况?与大多数涉及React钩子的事情一样,所涉及对象的标识(例如,您使用
==
测试的内容)在这里很重要。当费用
的标识与上次渲染不同时,将触发效果
选择器A 这个钩子返回Redux状态的
expenses
属性的items
属性。如果状态不变,则项
属性的标识也不会改变
const expenses=useSelector(({expenses}:RootState)=>expenses.items);
选择器B 这将返回调用items数组上的
filter
的结果。filter方法返回一个全新的数组
const expenses=useSelector({expenses}:RootState)=>
费用.项目.过滤器((费用:费用)=>!费用.已删除)
);
您观察到的是选择器B在每次组件渲染时都返回一个新值,因此效果被触发的频率太高 现在-如果状态未更改,但仅当传递给它的选择器函数的标识保持不变时,才重新使用。您可以通过在模块作用域中命名选择器而不是组件来确保这一点
const filteredExpenses=({expenses}:RootState)=>
费用.项目.过滤器((费用:费用)=>!费用.已删除);
常量MyComponent=()=>{
const[badgeValue,setBadgeValue]=useState(0);
施工费用=使用选择器(过滤器费用);
useffect(()=>{
const setBadge=async()=>{
const badgeNumber=等待计算请求badgeNumber(费用);
setBadgeValue(徽章编号);
};
setBadge();
return()=>setBadgeValue(0);
},[费用];
返回;
};