React-redux 在创建数组时重新呈现
React-redux rerenders when creating arrays
我有一个连接的组件,我想在其中检索对象数组。在我的商店中,有一个 ID 数组和一个对象,我在其中保存如下物品:
const state = {
items: [0, 1, 2],
itemsById: {
0: {},
1: {},
2: {},
},
}
所以使用 react-redux 的 connect
函数,我在我的组件中这样做以注入正确的数组:
const mapStateToProps = (state) => ({
items: state.items.map((itemId) => state.itemsById[itemId]),
})
我的应用程序触发更新非常频繁(我在 requestAnimationFrame
中调度操作),但 items
数组在此过程中不会更改。通过使用 React Perf 插件分析应用程序,似乎我连接的组件进行了不必要的渲染,我不明白为什么,因为状态中的 items
没有改变。
我已经尝试使用 reselect 创建一个记忆化的选择器,但它似乎没有改变任何东西。
更新(解决方案)
当您使用通过重新选择创建的选择器时,它会起作用。我的问题出在选择器本身:我的 items
数组位于一个更新非常频繁的父对象中,我选择了这个对象而不是直接选择 items
数组。
不要这样做:
const parentSelector = (state) => state.parent
const itemsByIdSelector = (state) => state.itemsById
const selector = createSelector(
parentSelector,
itemsByIdSelector,
(parent, itemsById) => parent.items.map(...)
)
这样做:
const itemsSelector = (state) => state.items
const itemsByIdSelector = (state) => state.itemsById
const selector = createSelector(
itemsSelector,
itemsByIdSelector,
(items, itemsById) => items.map(...)
)
每次调用 connect 时,您都在创建一个新数组:
const mapStateToProps = (state) => ({
items: state.items.map((itemId) => state.itemsById[itemId]),
})
为了防止这种情况,使用 memoized selector, which will return the same array every time, unless something actually changed. A selector is a method that computes the derived data from the state. Reselect 是用于 redux 的备忘选择器库。
我有一个连接的组件,我想在其中检索对象数组。在我的商店中,有一个 ID 数组和一个对象,我在其中保存如下物品:
const state = {
items: [0, 1, 2],
itemsById: {
0: {},
1: {},
2: {},
},
}
所以使用 react-redux 的 connect
函数,我在我的组件中这样做以注入正确的数组:
const mapStateToProps = (state) => ({
items: state.items.map((itemId) => state.itemsById[itemId]),
})
我的应用程序触发更新非常频繁(我在 requestAnimationFrame
中调度操作),但 items
数组在此过程中不会更改。通过使用 React Perf 插件分析应用程序,似乎我连接的组件进行了不必要的渲染,我不明白为什么,因为状态中的 items
没有改变。
我已经尝试使用 reselect 创建一个记忆化的选择器,但它似乎没有改变任何东西。
更新(解决方案)
当您使用通过重新选择创建的选择器时,它会起作用。我的问题出在选择器本身:我的 items
数组位于一个更新非常频繁的父对象中,我选择了这个对象而不是直接选择 items
数组。
不要这样做:
const parentSelector = (state) => state.parent
const itemsByIdSelector = (state) => state.itemsById
const selector = createSelector(
parentSelector,
itemsByIdSelector,
(parent, itemsById) => parent.items.map(...)
)
这样做:
const itemsSelector = (state) => state.items
const itemsByIdSelector = (state) => state.itemsById
const selector = createSelector(
itemsSelector,
itemsByIdSelector,
(items, itemsById) => items.map(...)
)
每次调用 connect 时,您都在创建一个新数组:
const mapStateToProps = (state) => ({
items: state.items.map((itemId) => state.itemsById[itemId]),
})
为了防止这种情况,使用 memoized selector, which will return the same array every time, unless something actually changed. A selector is a method that computes the derived data from the state. Reselect 是用于 redux 的备忘选择器库。