我正在尝试合并来自两个 websocket 的数据,这些数据被保存到两个适配器中。问题是我需要对这些聚合数据进行求和,并拥有一个输出数组,该数组在从两个父套接字更新时会更新。
问题,这个选择器可以吗?
export const selectLiveBalances = (state: RootState): LiveBalanceValue[] => {
const balances = selectBalanceCurrencies(state) // enumArray[]
return balances.map((code) => selectLiveBalanceByCode(state, code)) // selectLiveBalanceByCode working as intended
}
selectBalanceCurrency 是来自适配器的记忆选择器,它被重命名为
selectIds
,selectLiveBalances 是一个重新选择 createCachedSelector
,它缓存两个适配器的结果 selectById
selectById
然后我有第三个选择器,它采用 selectLiveBalances 并对实时余额数据求和。
我尝试只使用 selectByCode 但它们的要求集需要
selectLiveBalances
数组的总和和部分总和
我的阅读 重新选择 - 调用另一个选择器的选择器? - 我无法从中解析我的问题的解决方案 https://github.com/taskworld/rereselect - 这可以工作,但没有维护 https://github.com/reduxjs/reselect/issues/360 - 这与我试图解决的问题相同
某种将选择器聚合在一起的解决方案
当前选择器函数实现的主要问题是,它至少有一部分是动态的,并且取决于第一个
selectBalanceCurrencies
选择器输出的结果。据我所知,您无法编写具有动态输入的单个选择器函数。
您可能可以做的是创建一个“实用程序”选择器函数,该函数接受所有
CurrencyCode
键并输出每个状态的当前值,然后可以将此数组/对象用作另一个选择器的输入可以使用 selectBalanceCurrencies
返回的货币/余额键并聚合计算值。
示例实现可能如下所示:
// Selects the current balances state
export const selectBalances = (state: RootState): LiveBalanceValue[] => {
return state.balances;
};
// Recomputes a map/lookup object when selectBalances updates
export const selectBalancesByCodes = createSelector(
[selectBalances],
(balances) => balances.reduce((balancesByCode, balance) => ({
...balancesByCode,
[balance.code]: balance
}), {}),
);
// Recomputes array of live balances when either of selectBalanceCurrencies
// or selectBalancesByCodes selectors update
export const selectLiveBalances = createSelector(
[
selectBalanceCurrencies,
selectBalancesByCodes,
],
(balanceCurrencies, balancesByCodes) => {
return balanceCurrencies.map((code) => balancesByCodes[code]);
},
);