0

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

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 减速器实际上被调用,并修改了状态,但仍然没有重新渲染发生。所以 redux 不能接受它。但是根据文档,Redux 工具包使用 Proxy 对象作为状态并进行比较以查看它是否被修改。

我尝试过的事情:

state = initialState;

state = { ...initialState };

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

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

4

2 回答 2

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;
于 2022-01-06T07:07:04.100 回答
1

原来这是解决方案:

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

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

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

于 2020-05-19T14:20:02.820 回答