Redux Tollkit 使用和对比

83 阅读2分钟

Redux Tollkit

Redux Tollkit 官网

简介

Redux Toolkit 是 Redux 官方强烈推荐,开箱即用的一个高效的 Redux 开发工具集。它旨在成为标准的 Redux 逻辑开发模式,我们强烈建议你使用它。

使用流程

1.使用 configureStore 创建 store 对象

import {configureStore} from "@reduxjs/toolkit";
import reduxLogger from "redux-logger";
import reduxThunk from "redux-thunk";
import taskSliceReducer from "./features/taskSlice";

const store = configureStore({
  // 指定 reducer
  reducer: {
    // 按照模块划分各个切片
    taskSlice: taskSliceReducer,
  },
  // 使用中间件,如果不指定中间件,则默认集成 reduxThunk 指定了,就会全量覆盖 middleware 内容
  middleware: [reduxLogger, reduxThunk],
});

export default store;

configureStore.png

2.创建切片

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

// 创建切片
const taskSlice = createSlice({
  // 切面名称
  name: "task",
  // 切面的 reducer 中 state 的初始值
  initialState: {
    taskList: null,
  },
  // 编写不同的业务逻辑,用来修改公共状态。相当于 reducer 的 case 部分。
  reducers: {
    getAllTask(state, action) {
      // state:redux 中的公共状态信息【基于 immer 库管理,无需自己再克隆】
      // action:派发的行为对象,我们无需考虑标记问题(type),传递的其他信息都在 action.payload 中
      // ToDo payload 在 redux-promise 库中见到过
      console.log("state:", state, "action:", action);
      state.taskList = action.payload;
    },
  },
});

console.log("taskSlice:", taskSlice);

// 可以直接从切片的 actions 中获取到 actionCreator 对象,如果需要触发的话,执行 dispatch(actionCreator) 就可以了
export let {getAllTask, removeTask, updateTask} = taskSlice.actions;
console.log(taskSlice.actions.getAllTask()); // { "type": "task/getAllTask", apayload: undefined }

export default taskSlice.reducer;
/**
 * 实现异步触发,借助 redux-thunk
 */
export const getAllTaskListAsync = () => {
  return async (dispatch) => {
    let list = [];
    try {
      list = await new Promise((resole) => {
        setTimeout(() => {
          resole([{id: 0, state: 1, complete: ""}]);
        }, 3000);
      });
    } catch (_) {}
    console.log("list:", list);
    dispatch(getAllTask(list));
  };
};

createSlice.png

注意: slice.actions 的函数 和 reducer 中的函数,只是函数名一样,它们是两个函数

slice的actions.png

slice 对象打印

slice.png

3.函数组件触发

函数组件使用 react-redux 提供的 useSelectoruseDispatch

import { PureComponent, useEffect } from 'react';
import './App.css';
import { getAllTaskListAsync, getAllTask, removeTask, updateTask } from './store/features/taskSlice';
import { useSelector, useDispatch, connect } from 'react-redux';

function App() {
  // 获取公共属性,useSelector 入参可以获取 configStore.reducer 内容,返回的是对应分片的 state 信息
  let { taskList } = useSelector(state => state.taskSlice);
  // 获取派发方法
  let dispatch = useDispatch();
  useEffect(() => {
    console.log('taskList:', taskList);
    dispatch(getAllTaskListAsync());
  }, [])
  
  return (
    <div className="App">
      <h2>测试使用 Redux Toolkit</h2>
      {
        taskList && taskList.map(({id, state, complete}) => {
          return (
            <div key={id}>
              | <span>id: {id}</span> | <span>state: {state}</span> | <span>complete: {complete}</span> | <br />
            </div>
          )
        })
      }
    </div>
  );
}

export default App;

useSelector&useDispatch.png

4.类组件中触发

类组件还是用 connect 组织数据。 slice.actions 简化了 actionCreator 书写。

import { PureComponent, useEffect } from 'react';
import './App.css';
import { getAllTaskListAsync, getAllTask, removeTask, updateTask } from './store/features/taskSlice';
import { useSelector, useDispatch, connect } from 'react-redux';

class App extends PureComponent{
  componentDidMount() {
    this.props.getAllTaskListAsync();
  }

  render() {
    return (
      <div className="App">
        <h2>测试使用 Redux Toolkit</h2>
        {
          this.props.taskList && this.props.taskList.map(({id, state, complete}) => {
            return (
              <div key={id}>
                | <span>id: {id}</span> | <span>state: {state}</span> | <span>complete: {complete}</span> | <br />
              </div>
            )
          })
        }
      </div>
    );
  }
}

const mapStateToProps = state => state.taskSlice
const mapDispatchToProps = {
  getAllTask, removeTask, updateTask, getAllTaskListAsync
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

clazzUse.png