【问题标题】:React + Redux - Update local state on store change => infinity loopReact + Redux - 在存储更改时更新本地状态 => 无限循环
【发布时间】:2021-03-25 03:07:27
【问题描述】:

我有一个驻留在 store 中的数组,我们称它为 users,我有一个自定义钩子可以从 store 中检索它(通过 useSelector)。基于商店中的这个数组,我的组件中有一个本地状态,我将其用作表格的显示源。由于我根据搜索功能过滤数据,因此我需要将其单独保存在本地状态。

我想要做的是,每当存储中的数据发生变化时,我也想更新本地状态以反映这些变化(但事先在其上调用过滤函数)。

然而,这会导致无限循环,因为 useEffect + setState 会导致重绘,从而再次更改存储变量等。

const users = useUsers() // uses redux store
const [displayUsers, setDisplayUsers] = useState(users) // local state

useEffect(() => {
   const filteredUsers = onSearch(users) // applies the filtering
   setDisplayUsers(filteredUsers) // updates the local state
}, [users])

return <Table source={displayUsers} ... />

有人可以帮忙吗?

【问题讨论】:

  • “我需要将它单独保存在本地状态,因为我根据搜索功能过滤数据。”只需存储过滤器参数(搜索词或其他)并将其应用于来自 redux 的用户。
  • 但我没有看到您的代码将在哪里更新 Redux 存储并导致 users 发生更改。所以我认为这可能是一个记忆问题,你想使用来自reselect 的记忆选择器或浅等于检查以确保users 始终是同一个数组,除非存储状态发生实际变化。

标签: reactjs redux react-hooks infinite-loop react-state


【解决方案1】:

由于displayUsers是从props派生出来的,所以不需要在状态下维护它。每当 props 发生变化时即时计算它,如果组件由于其他原因经常渲染,则使用 memo:

const users = useUsers() // uses redux store

const displayUsers = useMemo(() => onSearch(users), [onSearch, users])

return <Table source={displayUsers} ... />

如果您确实需要在存储更改时设置状态,请确保选择器已被记忆 - 即如果没有任何更改,您将获得相同的数组。所以在重新渲染组件时,选择器会返回相同的users 数组,这会阻止useEffect 再次被调用。

您可以使用equalityFn(第二个参数)调用useSelector,以避免在没有任何更改的情况下返回新值(see Equality Comparisons and Updates)。这是文档中的示例:

import { shallowEqual, useSelector } from 'react-redux'

const selectedData = useSelector(selectorReturningObject, shallowEqual)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-05
    • 2019-11-11
    • 1970-01-01
    相关资源
    最近更新 更多