我创建了选择器来获取用户列表,如下所示:
const selectGroup = (state) => state.group;
const selectGroupUsers = createSelector(
[selectGroup],
(group) => group.get('users').toJS()
)
我的使用方法如下:
const users = useSelector(selectGroupUsers);
这些工作正常。
现在我尝试使用动态路径获取特定的用户信息:
const selectUser = createSelector(
[selectGroup, (_, path)],
(group, path) => group.getIn(path).toJS()
)
我的使用方法如下:
const path = ['users', 5, 'data'] // this is a dynamic array value from props
const userData = useSelector(state => selectUser(state, path));
这可行,但是我收到很多 redux 警告:
使用相同的选择器调用时,未知选择器返回不同的结果 参数。这可能会导致不必要的重新渲染。
我该如何解决这个问题?
我尝试按如下方式拆分选择器,但没有成功:
const selectGroup = (state) => state.group;
const selectPath = (state, path) => path;
const selectUser = createSelector(
[selectGroup, selectPath],
(group, path) => group.getIn(path).toJS()
)
** 更新
我重写了逻辑:
const selectUser = (path) => {
return createSelector(
[selectGroup, () => path],
(group, path) => group.getIn(path).toJS()
)
}
然后:
const userData = useSelector(selectUser(path));
这似乎有效!错误/警告消失了。我不知道为什么。这是正确的模式吗?
[selectGroup, selectPath]
或 [selectGroup, (_, path) => path]
应该 有效,但这取决于 path
的值,因为这通常仅适用于基元。
您似乎正在传递一个数组,如果您将
path
重新声明为一个新的 ['users', 5, 'data']
数组引用每个渲染周期,那么这将导致输入选择器每次更改并触发 selectUser
选择器函数每次都重新计算。
如果你想使用:
const selectUser = createSelector(
[selectGroup, (_, path) => path],
(group, path) => group.getIn(path).toJS()
);
然后我建议尝试记住传递给选择器的
path
值。这可能适合你。
示例:
const path = React.useMemo(() => {
return ['users', 5, 'data'];
}, [/* whatever the appropriate dependencies are */]);
const userData = useSelector(state => selectUser(state, path));
或者,您可以将
path
数组值分解为可以正确记忆的各个参数。
示例:
const selectUser = createSelector(
[
selectGroup,
(_state, users) => users, // users string
(_state, _users, value) => value, // value number
(_state, _users, _value, data) => data, // data string
],
(group, users, value, data) => group.getIn([users, value, dat]).toJS()
);
const userData = useSelector(
state => selectUser(state, 'users', 5, 'data')
);