【问题标题】:redux-toolkit state change in extraReducer does not initiate rerenderextraReducer 中的 redux-toolkit 状态更改不会启动重新渲染
【发布时间】:2020-09-05 14:40:00
【问题描述】:

我正在尝试同时注销和清除商店,所以点击我发送这个:

dispatch({type: PURGE, key: 'root', result: () => { } });

Redux persist 捕获它,并报告清除存储。伟大的。 在另一个减速器中,我捕获了该调度,并像这样删除了我的访问令牌:

import { PURGE } from 'redux-persist/es/constants';

const authSlice = createSlice({
  name: 'auth',
  initialState,
  reducers: {
    setAccessToken(state: AuthState, action: PayloadAction<Auth>): void {
      state.accessToken = action.payload.accessToken;
      state.expiresIn = action.payload.expiresIn;
    },
  },
  extraReducers: {
    [PURGE]: (state: AuthState, action: string): void => {
      state.accessToken = initialState.accessToken;
      state.expiresIn = initialState.expiresIn;
    },
  },
});

实际调用了 PURGE reducer,并修改了状态,但仍然没有发生重新渲染。所以 redux 不能接受它。但根据文档,Redux 工具包使用 Proxy 对象作为状态并进行比较以查看它是否被修改。

我尝试过的事情:

state = initialState;

state = { ...initialState };

没用。存储工作并保存数据,其他操作工作。我该如何进行?

编辑:进一步调试显示我自己的 reducer 在 redux-persist reducer 之前被调用,redux-logger 报告我的 reducer 根本没有改变状态。

【问题讨论】:

    标签: react-native react-redux redux-toolkit


    【解决方案1】:

    结果证明这是解决方案:

      extraReducers: {
        [PURGE]: (state: UserState, action: string): UserState => ({
          ...state,
          ...initialState,
        }),
      },
    

    我不明白为什么,根据documentation,修改状态对象也应该起作用:

    为了让事情变得更简单,createReducer 使用 immer 让你编写 减速器就好像它们直接改变状态一样。在现实中, reducer 接收到一个代理状态,它将所有突变转换为 等效的复制操作。

    【讨论】:

    • 有什么新信息吗? extraReducers mutalbe 和 reducers 是一样的吗?
    • @DmitryPapka,我可以像使用reducers 一样使用extraReducers 来更新状态。工作得很好。
    【解决方案2】:

    我遇到了类似的问题(不是重新渲染),今天通过这个帖子来了: 好像你不能完全替换状态对象。

    发件人:https://redux-toolkit.js.org/usage/immer-reducers

    有时您可能想更换 整个现有状态,要么是因为您加载了一些新数据,要么 您想将状态重置为其初始值。

    警告一个常见的错误是尝试分配 state = someValue 直接地。这行不通!这仅指向本地状态 变量到不同的引用。这既不是改变 内存中现有的状态对象/数组,也不返回一个全新的 值,因此 Immer 不会进行任何实际更改。

    const initialState = []
    const todosSlice = createSlice({
      name: 'todos',
      initialState,
      reducers: {
        brokenTodosLoadedReducer(state, action) {
          // ❌ ERROR: does not actually mutate or return anything new!
          state = action.payload
        },
        fixedTodosLoadedReducer(state, action) {
          // ✅ CORRECT: returns a new value to replace the old one
          return action.payload
        },
        correctResetTodosReducer(state, action) {
          // ✅ CORRECT: returns a new value to replace the old one
          return initialState
        },
      },
    })
    

    所以

    state = initialState;
    

    return initialState;
    

    【讨论】:

      猜你喜欢
      • 2021-06-22
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 2019-05-07
      • 2020-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多