redux入坑.md 4.8 KB

Redux不完全指南

官方文档

Redux是基于React的一个统一状态管理库。可以更容易实现组件间的状态共享问题,同时可以通过React DevTools工具记录并调试。

1. 安装

npm i redux @reduxjs/toolkit;

2. 基础使用

  1. 安装必要的库
  2. src文件夹创建名为store文件夹,并在里边新增一个index模块。
  3. index模块中定义store实例,并默认导出
  4. 在项目的入口模块中,将store实例注入到整个应用程序中。需要从react-redux中引入Provider组件,通过该组件将store注入进去

2.1 核心概念

  1. State:与Vuex一样,用来统一存储所有的状态
  2. Action:是一个对象,里边会包含两个属性:
    • type: 必需的。通过type决定如何修改状态。
    • payload: 可选的。用于传递额外参数。
  3. Reducer:可以是一个函数,定义修改状态的方法以及返回新状态;也可以是一个对象,里边包含多个reducer函数,通过combineReducers函数合并成一个大的reducer函数。每一个reducer函数接收两个参数
    • state:定义初始状态
    • action:action对象。

2.2 组件引入状态

现在React已经进入Hook时代,因此 可以通过 useSelector hook来从整个状态对象选出您所需的状态。

let selected = useSelector(selector)

  • selector:是一个选择状态的函数。接收一个参数,为store中的整个状态对象,并返回您要 的状态值即可。
  • useSelector返回值 就是 selector函数的返回值

2.3 状态修改

Redux中修改状态的唯一方式:dipatch一个action对象。reducer函数在执行时根据不同的action.type完成状态修改 并 返回新状态。

通过 react-redux库中的useDispath hook来获取 到 dispath 函数。在调用时传入一个action对象即可完成状态修改.

const dispatch = useDispatch()
dispatch({type: '', payload: 10})

3. slice的使用

在 RTK 包中引入createSlice函数来创建一个slice对象。

const slice = createSlice(options) 其中options对象包含以下常用属性

  • name:给action对象的type属性指定命名空间

  • initialState:指定状态的初始值

  • reducers:在该对象中定义各种修改状态的reducer函数

    • reducer函数都可以接收两个参数:state整个slice下的状态对象 以及 action对象
    • slice中reducer函数都可以直接通过state修改状态,无需在返回新状态

      import { createSlice } from '@reduxjs/toolkit';
        
      export const counterSlice = createSlice({
      name: 'counter',
      initialState: {
      value: 0,
      },
      reducers: {
      addOne(state) {
      state.value++;
      },
      },
      });
      //! counterSlice.actions对象包含所有与reducers函数同步的action对象creator函数
      export const { addOne } = counterSlice.actions;
        
      // counterSlice.reducer 就是 最终counter状态的修改函数
      export default counterSlice.reducer;
      

## 4. 异步处理

Redux原生不支持异步处理机制,需要我们通过一些中间件去完成。

好在,Redux Toolkit中内置了Thunk中间件可以完成异步任务处理。因此 在UI组件中调用dispatch时,不仅可以传入一个Action对象,还可以传入一个thunk函数,由其处理异步任务有结果后,在dispatch一个action去修改状态。

那么,什么是Thunk函数?

  • 可以是普通函数,也可以是async 函数
  • 函数会接收两个参数:dispatch 以及 getState函数
  • dispatch 顾名思义,用来异步处理后,执行状态修改的
  • getState 用来获取完整的store中的状态对象,以备之需

    //! 实现异步处理
    //* 通过定义一个thunk函数 去完成异步任务即可
    export function asyncAddOne(dispatch, getState) {
    //* getState调用后返回整个store中的状态对象,而不是某个slice下的状态
    let state = getState();
    console.log(state);
      
    // 异步任务
    setTimeout(() => {
      dispatch(addOne());
    }, 1000);
    }
    

Counter组件中,

  import Styles from './counter.module.css';
  import { useSelector, useDispatch } from 'react-redux';
  // 引入Thunk函数
  import { asyncAddOne } from './counterSlice';
  
  function Counter() {
    const dispatch = useDispatch();
    let count = useSelector(({ counter }) => counter.value);
    return (
      <div className={Styles.counter}>
        <p>计数:{count}</p>
        <p>
          <button
            onClick={() => {
              //! dispatch时传入thunk函数
              dispatch(asyncAddOne);
            }}
          >
            aysnc add
          </button>
        </p>
      </div>
    );
  }
  
  export default Counter;