问题描述
我在 rootReducer 中有 redux 选择器:
export const getUser = (state) => fromUser.userGetter(state.user);
export const getUsers = (state) => fromUsers.getUsers(state.users);
// this one is just a function where 1st parameter is array,2nd is string of ID
export const getUserNameById = (users,id) => {
let user = ''
if(users)
user = users.find(user => user._id === id).name
return user
}
// this one is selector,which does work fine
export const getUserName = createSelector([getUsers,getUser],(users,id) => {
let user = ''
if(users)
user = users.find(user => user._id === id).name
return user
});
但是当我尝试这样做以节省代码行时:
export const getUserName = createSelector([getUsers,getUserNameById (getUsers,getUser));
它通过说 getUsers.find 不是一个数组给我错误,实际上当我 console.log(getUser) 它没有从商店返回一个数组,而是返回一个函数 getUsers(state)。任何想法我该怎么办?谢谢!
解决方法
@FrozenKiwi 是正确的,你只需要传递函数而不是调用它。
export const getUserName = createSelector([getUsers,getUser],getUserNameById);
在运行时,您作为第二个参数传递的函数将使用第一个参数的选择器选择的值调用。创建的选择器基本上是这样的,但有记忆:
const getUserName = (state) => getUserNameById(getUsers(state),getUser(state));
假设 getUser
只返回一个 id
,这将起作用。但是这个名字暗示它可能会返回一个完整的用户对象?所以仔细检查一下。
如果 users.find
未返回匹配项,则当前代码中存在潜在的运行时错误。我建议像这样清理它:
export const getUserNameById = (users,id) => {
return (users || []).find( user => user._id === id)?.name || '';
}
- 如果未定义
(users || [])
则使用空数组,以便您始终可以调用find
。我这样做而不是设置默认值users = []
,因为如果可选参数出现在必需参数之前,一些 linter 会抱怨。 - 仅在找到用户时使用可选链
?.
访问name
- 如果
name
为假,则返回一个空字符串