React Redux的useSelector钩子中使用map遍历数组结果异常如何解决?
useSelector中执行数组遍历的问题解答
在Redux的useSelector钩子中执行数组遍历、map转换操作是完全合法的,你的实现思路不存在本质错误,结果不符合预期通常是以下几个原因导致的:
常见原因
- useSelector默认使用**严格引用相等(
===)**做返回值对比:你的当前写法每次执行selector时,map都会生成一个全新的数组实例,哪怕state.data没有任何变化,返回的数组引用也和上一次执行结果不同。这一方面会导致组件不必要的重复渲染,另一方面如果你的后续逻辑依赖引用相等判断,就会出现不符合预期的表现。 - Redux state取值路径错误:请先确认根store中
data字段的挂载位置和你selector中写的state.data完全匹配,如果data是挂载在某个子reducer下(比如state.user.data),路径写错自然无法拿到目标值。
修复方案
基础修复(无需性能优化)
先打印完整的state确认取值路径正确,你当前的代码逻辑本身可以正确返回如下结构的数组:
[ { total: 1, height: "3ft", weight: "34 lbs" }, { total: 30, height: "1ft", weight: "16 lbs" } ]
如果路径正确依旧拿不到值,请排查Redux的reducer逻辑是否正确更新了data字段。
优化重渲染
如果要避免不必要的重渲染,可以传入Redux提供的shallowEqual作为useSelector的第二个参数,会对数组内的元素做浅对比:
import { shallowEqual, useSelector } from 'react-redux' const test = useSelector(state => state.data.map(e => e.details), shallowEqual)
高性能派生数据方案
如果你的转换逻辑更复杂、或者会在多个组件中复用,建议使用reselect创建带缓存的selector,只有当state.data发生变化时才会重新执行map计算:
// selector.js import { createSelector } from '@reduxjs/toolkit' const selectData = state => state.data export const selectAllDetails = createSelector( [selectData], data => data.map(e => e.details) ) // 组件内调用 import { selectAllDetails } from './selector.js' const test = useSelector(selectAllDetails)
内容的提问来源于stack exchange,提问作者Karina Turtle
相关产品推荐
相关产品推荐

