使用Reselect从Redux Store中获取各项目的指定totalDevices值
解决Reselect选择器获取项目totalDevices的问题
看起来你已经搭好了基础的Redux和Reselect结构,只是需要针对你的deviceCount状态结构调整选择器的写法,分两种场景给你解决方案:
1. 为单个列表项获取对应项目的totalDevices
因为你的组件是列表中的每一项(LandingProjectsListItem),每个项对应一个唯一的projectId,所以需要创建参数化的Reselect选择器,接收projectId作为参数来定位对应的数据:
第一步:编写参数化选择器
import { createSelector } from "reselect"; // 基础选择器:获取Redux store中的deviceCount状态 const getDeviceCountState = (state) => state.deviceCount || {}; // 参数化选择器:根据传入的projectId获取对应的totalDevices export const getDeviceCountForProject = createSelector( // 依赖:1. deviceCount状态;2. 组件传入的projectId [getDeviceCountState, (state, projectId) => projectId], (deviceCount, projectId) => { // 拼接store中对应的key格式:projectId:xxx const stateKey = `projectId:${projectId}`; // 安全取值,避免不存在的key导致报错,默认返回0 return deviceCount[stateKey]?.totalDevices || 0; } );
第二步:修改组件的mapStateToProps
因为需要传递组件自身的projectId给选择器,所以不能再用createStructuredSelector(它无法接收组件的props参数),改成函数形式的mapStateToProps:
const mapStateToProps = (state, ownProps) => ({ // ownProps包含组件接收到的所有props,这里取列表渲染时传入的projectId count: getDeviceCountForProject(state, ownProps.projectId), }); export default connect( mapStateToProps, mapDispatchToProps )(withStyles(styles)(LandingProjectsListItem));
这样你的TotalDevicesAvatar里的{count}就会渲染当前项目对应的totalDevices数值了。
2. 获取所有totalDevices大于0的项目(如果需要在父组件筛选)
如果你的需求是先筛选出所有设备数大于0的项目,再渲染列表,可以编写另一个选择器来处理筛选逻辑:
export const getNonZeroDeviceProjects = createSelector( [getDeviceCountState], (deviceCount) => { // 将deviceCount对象转成数组,筛选出totalDevices>0的项 return Object.entries(deviceCount) .filter(([key, deviceData]) => deviceData.totalDevices > 0) .map(([key, deviceData]) => { // 提取出纯projectId(去掉前缀projectId:) const projectId = key.replace('projectId:', ''); return { projectId, totalDevices: deviceData.totalDevices }; }); } );
在父组件中使用这个选择器,就能拿到符合条件的项目数组,再遍历渲染子组件即可。
关键注意点
- 始终用**可选链操作符
?.**处理对象取值,避免因store中不存在对应key导致的报错 - 参数化选择器需要在
createSelector的依赖数组中加入(state, projectId) => projectId来接收外部参数 createStructuredSelector适合不需要组件props的场景,当需要依赖组件自身props时,改用函数式的mapStateToProps
内容的提问来源于stack exchange,提问作者jansyb04
相关产品推荐
相关产品推荐

