首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >React -过滤存储中的对象会导致递归/无限循环

React -过滤存储中的对象会导致递归/无限循环
EN

Stack Overflow用户
提问于 2020-09-20 04:05:47
回答 1查看 212关注 0票数 3

我在react应用程序中使用redux store来存储我的费用等数据。

现在,我在其中一个组件中使用这些费用来计算TODO徽章计数,如下所示

代码语言:javascript
复制
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]);

这与预期的一样。然而现在,当我想像这样过滤掉删除的费用时,我遇到了一个奇怪的副作用:

代码语言:javascript
复制
 const expenses = useSelector(({ expenses }: RootState) => 
     expenses.items.filter((expense: Expense) => !expense.deleted)
 );

这会导致调用useEffects的无限循环。为什么会发生这种情况?

EN

回答 1

Stack Overflow用户

发布于 2020-09-20 05:20:02

与大多数涉及React钩子的事情一样,所涉及的对象的身份(例如,您使用===测试的内容)在这里很重要。当expenses的标识与上次渲染不同时,将触发您的效果。

选择器A

此挂钩返回Redux状态的expenses属性的items属性。如果状态没有改变,items属性的标识也不会改变。

代码语言:javascript
复制
const expenses = useSelector(({ expenses }: RootState) => expenses.items);

选择器B

这将返回在items数组上调用filter的结果。filter方法返回一个全新的数组。

代码语言:javascript
复制
const expenses = useSelector(({ expenses }: RootState) => 
     expenses.items.filter((expense: Expense) => !expense.deleted)
);

您所观察到的是Selector B在组件每次呈现时都返回一个新值,因此该效果被频繁触发。

Now -如果状态没有改变,但仅当传递给它的选择器函数的标识保持不变时,使用useSelector cache its return value进行重用。您可以通过在模块作用域而不是组件中命名选择器来确保这一点。

代码语言:javascript
复制
const filteredExpenses = ({ expenses }: RootState) =>
  expenses.items.filter((expense: Expense) => !expense.deleted);

const MyComponent = () => {
  const [badgeValue, setBadgeValue] = useState(0);
  const expenses = useSelector(filteredExpenses);
  useEffect(() => {
    const setBadge = async () => {
      const badgeNumber = await calculateRequestBadgeNumber(expenses);
      setBadgeValue(badgeNumber);
    };

    setBadge();

    return () => setBadgeValue(0);
  }, [expenses]);
  return <StuffToRender />;
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63972966

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档