使用redux-toolkit改变状态的技巧

xesrikrc  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(156)

我正在使用redux-toolkit和React。我知道基本的redux(不使用redux-toolkit)不允许改变原始状态。这就是为什么我选择redux-toolkit来做这件事。但是,我不明白什么是使用redux-toolkit改变状态的禁止方式。我读了下面的一个官方文档,但它对我不起作用。
https://redux-toolkit.js.org/usage/immer-reducers
尤其是文档中的Immer Usage Patterns。Mutating and Return状态和Reset and Replacing状态有什么区别?看起来很相似。另外,我想不出文档中的Updating Nested Data。
你能告诉我一些使用redux工具包的技巧吗?

x3naxklr

x3naxklr1#

你链接到的页面的介绍有效地涵盖了Redux reducer函数在过去如何工作的一段历史。Redux状态被认为是不可变的,所以如果你想更新切片状态的任何部分,你必须浅拷贝所有你想更新的状态和嵌套状态。
请参见异径管和不可变状态:

function handwrittenReducer(state, action) {
  return {
    ...state,
    first: {
      ...state.first,
      second: {
        ...state.first.second,
        [action.someId]: {
          ...state.first.second[action.someId],
          fourth: action.someValue,
        },
      },
    },
  }
}

Redux-Toolkit附带了immer,所以我们可以编写可变的reducer函数,并且知道我们只是在编辑状态的草稿副本,该副本将以不可变的方式应用。
你对浸入式使用模式感兴趣,特别是变异和返回状态。
在任何给定的case reducer中,**Immer期望您要么 * 改变 * 现有的状态,要么自己构造一个新的状态值并返回它,但 * 不能 * 在同一个函数中同时使用这两种方法!**例如,这两种方法对于Immer都是有效的reducer:

const todosSlice = createSlice({
  name: 'todos',
  initialState: [],
  reducers: {
    todoAdded(state, action) {
      // "Mutate" the existing state, no return value needed
      state.push(action.payload)
    },
    todoDeleted(state, action.payload) {
      // Construct a new result array immutably and return it
      return state.filter(todo => todo.id !== action.payload)
    }
  }
})

您可以修改状态的一部分,更改将被正确应用或者*您可以返回一个完全新的状态对象,根据需要对其进行或多或少的更新。唯一禁止的是修改现有状态的一部分*返回一个新的状态对象引用。

禁止更新:

const todosSlice = createSlice({
  name: 'todos',
  initialState: {todos: [], status: 'idle'}
  reducers: {
    todoDeleted(state, action.payload) {
      // Construct a new array immutably
      const newTodos = state.todos.filter(todo => todo.id !== action.payload);

      // "Mutate" the existing state to save the new array
      state.todos = newTodos;

      return {
        ...state,
        status: 'complete',
      };
    }
  }
});

可接受的更新:

const todosSlice = createSlice({
  name: 'todos',
  initialState: {todos: [], status: 'idle'}
  reducers: {
    todoDeleted(state, action.payload) {
      // Construct a new array immutably
      const newTodos = state.todos.filter(todo => todo.id !== action.payload);

      // "Mutate" the existing state to save the new array
      state.todos = newTodos;
      state.status = 'complete';
    }
  }
});

相关问题