You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux Toolkit中createSelector获取根状态异常求助

Redux Toolkit中createSelector获取错误状态的问题

我正在用TypeScript结合Redux Toolkit开发项目,遇到一个奇怪的问题:部分createSelector调用时,传入的state不是预期的根状态,导致报错,但改用store.getState()直接获取状态就能正常运行。

状态结构说明

我的状态通过combineReducers组合了两个reducer:

const entities = combineReducers({
    trello: entityTrello,
    users: entityUser,
})

export function makeStore() {
    return configureStore({
        reducer: {
            entities: entities,
        },
        devTools: process.env.NEXT_PUBLIC_PROJECT_STATUS == "develop",
    })
}   

其中trello reducer存储boards和cards数据,users reducer存储用户列表,数据存入store后状态树结构是正常的。

正常工作的选择器

以下createSelector可以正确获取数据:

export const selectLanesByBoardId = () => {
    return useAppSelector<BoardData>(selector => createSelector(
        (state: AppState) => state.entities.trello.tables.data?.boards,
        (state: AppState) => state.entities.trello.tables.data?.lanes,
        (state: AppState) => state.entities.trello.tables.data?.cards,
        (state: AppState) => state.entities.trello.meta.boardId,
        (state: AppState) => state.entities.trello.meta.workspace,
        (boards, lists, cards, boardId, workspace) => {
            let data: Array<Lane>
            // 把键值对结构转为数组
            const laneIds = objectValues<TrelloBoard>(boards)?.find(value => value.id == boardId)?.lists
            // 根据laneIds筛选对应的lane对象
            const lanes = objectValues<TrelloLanes>(lists)?.filter(value => laneIds?.includes(value.id))
            // 给每个lane绑定对应的cards
            data = lanes.map(lane => ({
                ...lane,
                cards: objectValues<TrelloCard>(cards)
                    ?.filter(value => lane?.cards?.includes(value.id))
                    .map(value => ({
                        ...value,
                        draggable: workspace == "free",
                        laneId: lane.id
                    }))
            }))

            return {lanes: data} as BoardData
        }
    )(selector))
}

出错的选择器

但下面这个createSelector无法获取正确的根状态:

export const selectUsers = () => {
    return useAppSelector<Array<User>>(selector => createSelector(
        (state: AppState) => {
            return state.entities.users.tables.data?.users
        },
        (users) => {
            return users ?? []
        }
    )(selector))
}  

报错显示entities对象未定义。改用store.getState()则能正常运行:

export const selectUsers = () => {
    return useAppSelector<Array<User>>(selector => createSelector(
        (state: AppState) => {
            return store.getState().entities.users.tables.data?.users
        },
        (users) => {
            return users ?? []
        }
    )(selector))
}

补充信息

通过console.log发现,出错的选择器中传入的state并非预期的根状态,而是一个其他结构的对象。但我的reducer仅更新自身局部状态,并未修改根状态结构,例如:

state.tables.data && (state.tables.data = {
    ...state.tables.data,
    lanes: state.utils.nextStateAfterLastAction?.lanes ?? [],
    cards: state.utils.nextStateAfterLastAction?.cards ?? [],
})

请问为何部分createSelector无法拿到根状态,而store.getState()可以?


内容的提问来源于stack exchange,提问作者hassan moradnezhad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 21:09:29