簡體   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-2024 STACKOOM.COM