【问题标题】:What exactly should you return from a redux slice reducer?你应该从 redux slice reducer 中返回什么?
【发布时间】:2021-06-22 16:56:25
【问题描述】:

今天我遇到了一个错误,当我的 redux 状态发生变化时,我使用 useSelector 的组件不会重新渲染。快速阅读createSlice 文档后,我注意到他们返回了state.something = action.payload,而我没有这样做。

所以在这段代码中:

const personSlice = createSlice({
  name: "person",
  initialState,
  reducers: {
    setToken: (state, action) => {
      state.token = action.payload;
    },
    setUser: (state, action) => {
      state = { ...state, ...action.payload };
    },
  },
});

当我设置令牌时,我的应用程序会更新并且运行良好。但是在调度 setUser 操作之后,我依赖于 person 状态的组件没有得到重新渲染。但是为什么我设置令牌而不返回时它会起作用呢?

我将代码更改为:

const personSlice = createSlice({
  name: "person",
  initialState,
  reducers: {
    setToken: (state, action) => {
      state.token = action.payload;
    },
    setUser: (state, action) => {
      return state = { ...state, ...action.payload };
    },
  },
});

即使没有setToken 中的return,一切正常。

所以我想我的最终问题是,切片中究竟发生了什么,为什么以及我需要从操作中返回什么?

【问题讨论】:

    标签: reactjs redux redux-toolkit


    【解决方案1】:

    createSlice 在里面使用 Immer。 Immer 的工作方式是:

    • 跟踪变异到现有的state 对象,例如state.x = 123
    • 让您返回一个新值,例如`return {...state, x: 123}

    分配state = anything 不是突变,它不会返回任何东西。它只是重新分配名为state局部变量指向别的东西。

    如果你想“合并”一些数据,那么是的,你需要return {...state, ...someData},或者使用Object.assign(state, someData) 来“变异”现有的state 对象。

    请参阅涵盖此主题的the Redux Toolkit "Writing Reducers with Immer" usage guide

    【讨论】:

    • 所以如果我这样做 state.x = 123 它实际上并没有改变状态,但 Immer 只是“接受”变化并为我改变状态?
    • 是的。 Immer 使用代理跟踪您对draftState尝试更改,现在更改草稿以让您继续进行更改,但是一旦您完成创建最终的不可变内容,然后不可变地重播您的所有更改 -更新结果。
    • 谢谢你向我解释了一切。
    猜你喜欢
    • 2021-05-05
    • 2020-02-04
    • 2018-02-23
    • 1970-01-01
    • 2022-11-04
    • 2017-03-28
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多