如何解构ID数组传入useSelector获取各客户端对应条目列表?
解决方案
你当前的写法存在两个核心错误:
- 仅解构了
clientIds数组的第一个元素,天然只能拿到单条clientId对应的数据 useSelector的入参必须是接收完整Redux store作为参数的选择函数,你之前写的useSelector((getItemsByClientId(clientId)))直接把selector的执行结果当成了选择函数传入,本身不符合API规范,同时你调用getItemsByClientId时也漏传了必填的state参数。
在不额外新建selector的前提下,你可以直接在useSelector的回调函数中遍历所有clientId,批量拉取对应数据即可,参考实现:
// 获取所有已连接账户 const connectedAccounts = useSelector(getConnectedAccounts); // 提取全部clientId const clientIds = connectedAccounts.map(el => el.clientId); // 按clientId维度组装对应条目列表 const clientItemsList = useSelector(state => { return clientIds.map(clientId => ({ clientId, items: getItemsByClientId(state, clientId) })); });
如果不需要保留clientId和条目的绑定关系,只想拿到所有条目的扁平化数组,直接用flatMap替换map即可:
const allMergedItems = useSelector(state => { return clientIds.flatMap(clientId => getItemsByClientId(state, clientId)); });
如果你希望用对象结构存储、方便通过clientId快速查询对应条目,可以用你之前尝试的reduce实现,正确写法如下:
const clientItemsMap = useSelector(state => { return clientIds.reduce((resultMap, clientId) => { resultMap[clientId] = getItemsByClientId(state, clientId); return resultMap; }, {}); }); // 使用时直接通过 clientItemsMap[目标clientId] 即可取到对应条目
补充说明:如果你的getItemsByClientId是通过reselect创建的记忆化selector,上述遍历调用的写法不会破坏缓存性能,只要state对应片段和传入的clientId没有变化,就不会触发重复计算。
内容的提问来源于stack exchange,提问作者barth
相关产品推荐
相关产品推荐

