如何在 Redux Toolkit 减速器中替换整个状态?

Cer*_*ean 7 reactjs redux react-redux immer.js

编辑:解决方案是state在我完全替换它后返回( return state = {...action.payload})!但为什么?当我单独替换字段时,我不需要返回它。

我正在使用Redux Toolkit,它简化了一些 Redux 样板。他们做的一件事是使用 Immer 允许您直接“修改”状态(实际上,您不是)。它工作正常,除了我不知道如何完全替换我的状态部分。例如,我想做这样的事情

const reducer = createReducer({ s: '', blip: [] }, {

    [postsBogus.type]: (state, action) => {
        state = { ...action.payload };
    }
Run Code Online (Sandbox Code Playgroud)

state保持不变。相反,我必须这样做

[postsBogus.type]: (state, action) => {
    state.s = action.payload.s;
    state.blip = action.payload.blip;
}
Run Code Online (Sandbox Code Playgroud)

有没有办法可以完全替换状态?

mar*_*son 11

是的,正如您所指出的,您必须返回一个新值才能完全替换状态。

即使在“普通的”Redux reducer 中,赋值state = newValue也没有任何作用,因为所有这一切都表明,命名的局部函数变量state现在指向内存中的不同值。这对返回新值没有任何作用。

特别是对于 Immer,您可以改变Proxy-wrapped值的内容state只要它是一个对象或数组,或者您可以返回一个全新的值,但不能同时返回


Nor*_*mal 7

你可以,但不能以这种方式,当你说:

function x(y){
   y = 4
}
Run Code Online (Sandbox Code Playgroud)

您正在改变函数参数,但不是 redux 的状态,您有两种选择来更新 redux 存储的此状态:

要么设置state.your_state_name = something,要么在您的情况下,您想要做的是返回一个新对象,新对象就是新状态值。

简单的例子:

myReducerFunc: (state, action) => {
  return {...action.payload }
},
Run Code Online (Sandbox Code Playgroud)

另一个例子:

const loggedInUserSlice = createSlice({
  name: '$loggedInUser',
  initialState: {
    isLoggedIn: false,
  },
  reducers: {
    loggedIn: (state, action) => {
      return {
        isLoggedIn: true,
        ...action.payload,
      }
    },
  },
})
Run Code Online (Sandbox Code Playgroud)