Redux Toolkit 学习笔记

在 Redux 学习笔记笔记中我们已经对 Redux 有了一个大概的认识,接下来我们来链接一下Redux Tookit这个工具包。

在编写 Redux 的代码时,我们会编写很多的模块代码和业务逻辑代码,在编写过程中比较的繁琐,而Redux Tookit工具包可以简化 Redux 的开发步骤。

使用 Tookit 的 createSliceAPI 简化 Redux reducer 逻辑和 actions

首先我们先回顾一下以前是用 Redux 编写代码的过程,具体有如下的几个步骤:

  1. 创建Actions

    里面还有业务名称和对应函数传入的参数

  2. 创建Reducers

    Reducers通过 switch 语句来维护对应的 Action 和相应的业务处理,并且维护对应的State数据。

  3. 使用Store来关联ActionsReducers

以上就是使用 Redux 编写代码的过程,而createSliceAPI 为我们做了几件重要的事情:

  • 可以将 case reducer 编写为对象内部的函数,而不必编写 switch/case 语句
  • reducer 将能够编写更短的不可变更新逻辑
  • 所有 action creators 将根据我们提供的 reducer 函数自动生成

具体的实例代码如下:

const createSlice = require("@reduxjs/toolkit").createSlice;

const initialState = {
  numOfIcecreams: 10,
};

const icecreamSlice = createSlice({
  name: "icecream",
  initialState,
  reducers: {
    ordered: (state) => {
      state.numOfIcecreams--;
    },
    restocked: (state, action) => {
      state.numOfIcecreams += action.payload;
    },
  },
  extraReducers: (builder) => {
    builder.addCase(cakeActions.ordered, (state) => {
      state.numOfIcecreams--;
    });
  },
});

// 对外暴露相应的执行动作
module.exports = icecreamSlice.reducer;
module.exports.icecreamActions = icecreamSlice.actions;

使用 Tookit 进行 Store 的声明

使用createSliceAPI 我们只能实现 Redux reducer 和 actions,而最重要的 Store 并未实现。而使用 Tookit 来实现 Store 的很简单,具体的实例如下:

const configureStore = require("@reduxjs/toolkit").configureStore;
const cakeReducer = require("../features/cake/cakeSlice");

// 假如有多个Reducer的话都可以直接在这里声明
const store = configureStore({
  reducer: {
    cake: cakeReducer,
  },
});

调用 Store 的实例如下:

const store = require("./app/store");
const icecreamActions =
  require("./features/icecream/icecreamSlice").icecreamActions;

console.log("Initial State ", store.getState());
const unsubscribe = store.subscribe(() => {
  console.log("Updated State ", store.getState());
});
store.dispatch(cakeActions.ordered());
store.dispatch(cakeActions.ordered());
store.dispatch(cakeActions.ordered());
store.dispatch(cakeActions.restocked(3));

使用 Tookit 进行中间件使用

使用 Tookit 来声明中间件其实很简单,就比如我们使用redux-logger中间件为例,我们首先安装redux-logger中间件,然后在 Store 中进行声明。具体的实例如下:

const reduxLogger = require('redux-logger')
const logger = reduxLogger.createLogger()

const store = configureStore({
  reducer: {
    cake: cakeReducer,
  }
   middleware: getDefaultMiddleware => getDefaultMiddleware().concat(logger)
})

module.exports = store

使用 Tookit 声明额外的 Reducer

额外的 Reducer 主要是可以让同一个 slice reducer 监听其他 action types。

就比如一个商店中可以卖蛋糕和冰淇淋,但是随着业务的增长,顾客买了一个蛋糕我们就会送一个冰淇淋。这样当我们的蛋糕减一的时候,冰淇淋也会随着减一,我们就可以使用额外的 Reducer 来实现这个业务。

具体实现步骤如下:

  1. 声明蛋糕的 Slice
const createSlice = require("@reduxjs/toolkit").createSlice;

const initialState = {
  numOfCakes: 20,
};

const cakeSlice = createSlice({
  name: "cake",
  initialState,
  reducers: {
    ordered: (state) => {
      state.numOfCakes--;
    },
    restocked: (state, action) => {
      state.numOfCakes += action.payload;
    },
  },
});

module.exports = cakeSlice.reducer;
module.exports.cakeActions = cakeSlice.actions;
  1. 声明冰淇淋 Slice
const { cakeActions } = require("../cake/cakeSlice");

const createSlice = require("@reduxjs/toolkit").createSlice;

const initialState = {
  numOfIcecreams: 10,
};

const icecreamSlice = createSlice({
  name: "icecream",
  initialState,
  reducers: {
    ordered: (state) => {
      state.numOfIcecreams--;
    },
    restocked: (state, action) => {
      state.numOfIcecreams += action.payload;
    },
  },
  // 声明一个而外的Reducer,当蛋糕执行ordered的时候,冰淇淋就会减一
  extraReducers: (builder) => {
    builder.addCase(cakeActions.ordered, (state) => {
      state.numOfIcecreams--;
    });
  },
});

module.exports = icecreamSlice.reducer;
module.exports.icecreamActions = icecreamSlice.actions;

在 Tookit 中执行异步操作

使用 Tookit 实现异步也有对应的 API 函数可以使用,具体可以使用createAsyncThunk

此 API 功能函数主要接受两个参数:

  • 操作名称

    将用作生成的 action 类型的前缀的字符串,用于后续声明调用

  • 异步回调函数

    执行异步后返回异步结果的回调函数

createAsyncThunk它会根据返回的值自动分配生命周期操作的 Promise 对应的状态值,并可以使用 rducer 函数监听这些操作类型并执行必要的状态转换。

使用createAsyncThunk创建出来的操作可以通过dispatch来调用,也可以在而外的 Reducer 中声明使用,具体的实例如下:

const axios = require("axios");
const createSlice = require("@reduxjs/toolkit").createSlice;
const createAsyncThunk = require("@reduxjs/toolkit").createAsyncThunk;

const initialState = {
  loading: false,
  users: [],
  error: "",
};

const fetchUsers = createAsyncThunk("user/fetchUsers", () => {
  return axios
    .get("https://jsonplaceholders.typicode.com/users")
    .then((response) => response.data.map((user) => user.id));
});

const userSlice = createSlice({
  name: "user",
  initialState,
  extraReducers: (builder) => {
    builder.addCase(fetchUsers.pending, (state) => {
      state.loading = true;
    });
    builder.addCase(fetchUsers.fulfilled, (state, action) => {
      state.loading = false;
      state.users = action.payload;
      state.error = "";
    });
    builder.addCase(fetchUsers.rejected, (state, action) => {
      state.loading = false;
      state.users = [];
      state.error = action.error.message;
    });
  },
});

module.exports = userSlice.reducer;
module.exports.fetchUsers = fetchUsers;

调用异步函数

const fetchUsers = require("./features/user/userSlice").fetchUsers;

store.dispatch(fetchUsers());

你可能感兴趣的:(React,学习,笔记,javascript,React)