繁体   English   中英

Redux 工具包 useSelector state 即使调用操作也不更新

[英]Redux Toolkit useSelector state not updating even though action is called

我一直在努力反对这一点,希望能得到另一双眼睛会有所帮助。

我以一种非常简单的方式在 React Native 应用程序中使用 Redux + Redux 工具包。 我可以(通过日志语句)告诉我正在调用我的操作并且正在设置 state,但是我在 state 上的 useSelector 永远不会更新。 我也尝试过使用shallowEqual ,但不需要这样做,因为 Redux Toolkit 使用 Immer 并且 object 在更新后不应该通过相等性检查(我研究的大多数其他类似问题都是由于此)

这是我的主要部分,然后是所有相关代码。 请原谅代码转储,但我想给出一个完整的图片:


export interface Metadata {
    title: string
    author: string
    firstLines: string
    id: string
}

type MetadataState = Record<string, Metadata>

export const metadataSlice = createSlice({
    name: "metadata",
    initialState: {} as MetadataState,
    reducers: {
        setMetadata: (state: MetadataState, action: PayloadAction<MetadataState>) => {
            state = action.payload
            console.log("new metadata: ", state)
        },
        addMetadata: (state: MetadataState, action: PayloadAction<Metadata>) => {
            state[action.payload.id] = action.payload
        }
    }
});

我有一个异步操作来从 AsyncStorage(如移动设备上的 LocalStorage)加载元数据,如下所示:

export function loadMetadata() {
    return async (dispatch: AppDispatch, getState: () => RootState) => {
        const maybeMetadata = await AsyncStorage.getItem("metadata");
        if(maybeMetadata) {
            dispatch(metadataSlice.actions.setMetadata(JSON.parse(maybeMetadata)))
            return true
        } else {
            return false
        }
    }
}

我在我的主要组件中按如下方式发送它:

  const dispatch = useAppDispatch()

  useEffect(() => {
    dispatch(loadMetadata())
  }, [])

在另一个组件中,我试图通过以下方式访问 state:

const metadata = useAppSelector(state => state.metadata)

知道发生了什么事吗? state 似乎永远不会更新,即使我看到我的操作被调用并更新其中的 state。 是不是发送不正确? 我尝试使用store.getState()直接访问 state,而 state 似乎是空的,不知何故只是没有被设置?

老实说,我很迷茫,任何帮助表示赞赏。

这个问题与 Immer(Redux 工具包利用它来允许可变操作)的工作方式有关。

setMetadata: (state: MetadataState, action: PayloadAction<MetadataState>) => {
  state = action.payload
  console.log("new metadata: ", state)
}

我没有改变 state,而是重新分配了它,这打乱了 Immer 跟踪草稿状态的方式。 console.log 语句返回了新的 state,但它不适用于 Immer。 相反,我需要这样做:

setMetadata: (state: MetadataState, action: PayloadAction<MetadataState>) => {
  // simply return the new state, since I'm changing the whole state
  return action.payload
}

现在它工作正常。 我有点惊讶我没有看到这个记录(它可能在某个地方)或得到某种警告,但很高兴知道未来!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM