【问题标题】:How to use redux toolkit's preloadedState and createSlice together properly?如何正确使用 redux 工具包的 preloadedState 和 createSlice?
【发布时间】:2021-10-04 21:21:15
【问题描述】:

我正在尝试迁移到 redux 工具包,但遇到了一个问题。

这是一个简单的计数器切片示例。

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  value: 0,
};

export const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
  },
});

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;

这是一个使用 configureStore 创建的商店。

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./slice";

export const store = configureStore({
  reducer: {
    counter: counterReducer,
    // later, many other reducers will be added here.
  },
});

还有什么问题。

但是如果我引入preloadedState,那就有问题了。

const store = configureStore({
    reducer: counterReducer,
    preloadedState: {
      counter: {
         value: 10
      }
    },
  });

如果我像下面这样记录存储的状态,它会按预期记录。

   // without using preloadedState, it results to {counter: {value: 0}}
   console.log(store.getState())
   // with using preloadedState, it results to {counter: {value: 10}}
   console.log(store.getState())

但是在使用 slice reducer 的时候会出现一个问题,因为 slice reducer 使用的是自己的 state。

   ...
     reducers: {
       increment: (state) => {
         state.value += 1;  // not work anymore if using preloadedState. we have to use state.counter.value instead.
       },
       decrement: (state) => {
         state.value -= 1;  // not work anymore if using preloadedState. we have to use state.counter.value instead.
       },
     },
   ...

我们必须使用,

   ...
     reducers: {
       increment: (state) => {
         state.counter.value += 1; 
       },
       decrement: (state) => {
         state.counter.value -= 1;
       },
     },
   ...

所以问题是,我们是否必须添加条件语句,根据我们是否使用 preloadedState 来分离 slice reducer 内部的逻辑?

只要提供了 preloadedState,如果 slice reducer 使用 preloadedState 而不是使用它自己的状态,那就太好了。有没有更好的方法?

谢谢。

【问题讨论】:

    标签: redux redux-toolkit


    【解决方案1】:

    如果您查看您的 Redux Devtools 浏览器扩展程序,您会注意到 - 因为您只有一个 reducer,并且您将那个作为根 reducer 传递,所以您的 state 的形状为

    {
      value: 10
    },
    

    此时您的正常状态只是没有计数器减速器的子键,因为您的整个状态计数器减速器。

    如果你希望你的 state 有一个合理的结构(并且将来能够使用多个 reducer),你必须添加 reducer 键作为对象:

    const store = configureStore({
        reducer: {
          counter: counterReducer,
        },
        preloadedState: {
          counter: {
             value: 10
          }
        },
      });
    

    正如您将在开发工具中注意到的那样,现在您的状态结构是您所期望的 - 并且预加载的状态也将与之匹配。

    但请记住,从现在开始在选择器中您将不得不useSelector(state => state.counter.value)

    【讨论】:

    • omg..忘记添加键“counter”..感谢您的帮助!
    猜你喜欢
    • 2021-03-11
    • 1970-01-01
    • 2021-01-12
    • 2021-04-14
    • 1970-01-01
    • 2021-09-19
    • 2020-05-29
    • 2021-11-01
    相关资源
    最近更新 更多