Skip to content

Redux

涉及内容

  • redux
  • react-reducx
  • redux中间件
  • mobx
  • react-router-dom
  • redux-saga dva umi
  • antd pro

redux: 公共状态管理方案; 在中大体量 && 高频状态切换 && 复杂更新逻辑中使用; 父子组件一般通过props && redux 祖先 && 后代组件一般通过redux 特性

  • redux可以在非react中使用, 体积仅为2kb

使用

  1. 创建container: createStore([reducer]) && 规划reducer
  • store容器中, 存储状态 && 事件池;状态发生改变, 执行事件池中的方法;
  1. 获取状态(基于context获取store对象)
    • store.getState()
  2. 放入事件到事件池(必须保证视图更新 && 上下文为最新)
    • store.subscribe(func)
    • 类组件传递forceUpdate()即可
  3. 创建容器时,传递reducer
js
const init = {}
let reducer = function reduceer(state=init, action){
  // 不直接修改原状态; return时直接返回
  fixState = {...state}
  switch(action.type){
    // 根据不同状态, 修改不同信息
    ...
    default:

  }
  return state // 返回的信息替代公共状态——在第一次dispatch时, 设置初始值
}
  1. 任务分发, 执行reducer, 修改状态
  • store.dispatch({type: xxx })

具体例子:

jsx
function Component(){
  const store = useContext(store)
  const [time, setTime] = useState(new Time())
  const handle = ()=>{
    console.log("Extra operation.")
  }
  useEffect(()=>{
    // 创建新的context
    const unsubscript = store.subscribe(handle)
    store.dispatch(unsubscript)
    return ()=>{
      // 移除上一次的方法
      unsubscript()
    }
  }, [time])
  useEffect(()=>{
    store.subscribe(()=>{
      setXxx() // 同时保证视图渲染 && 上下文最新
    })
  })
  return (
    XXX
  )
}

function SubComponent(){
  const {stateExt} = store.getState()
  const handle = ()=>{
    sotre.dispatch({
      type: 'typeA'
    })
  }
  return (
    <>
      <Button onClick={handle}></Button>
    </>
  )
}

机制

  • 初次派发, 在redux内部派发; 手动dispatch均为二次派发之后
  • redux对象结构:
    • @@observable
    • dispatch
    • getState
    • replaceReducer
    • subscribe

react-redux

react-redux中间件

中间件本身就是一个加工管道, 通过不同的中间件实现不同的效果 使用

  • createStore(reducer, enhancer), 通过传入enhancer中间件实现对reducer的对应效果

    • js

    // 添加logger中间件 createStore(reducer, applyMiddleware(reduxLogger))

  • redux的action方法不支持异步, 支持异步需要使用middleWare 原因: 异步函数默认返回Promise包装对象, 其中React经过处理, 会将其变为action, 而默认情况下Promise是没有type属性的

    js
    // 通过redux-thunk中间件处理所要求的action格式, 基于redux-thunk
    // 实际上是派发了两次: 第一次返回异步函数, 实际上没有效果; 第二次在函数内部通过重写dispatch在中间件内部派发
    function action(){
      return async (dispatch)=>{
        await getData()
        dispatch({type: "xxx"})
      }
    }
    
    // 通过redux-promise中间件可以有更直观的代码书写: 内部重写dispatch, 监听promise实例, 当状态更改后进行dispatch; 派发单次, 自动处理
    async function action(){
      await getData()
      return {
        type: "xxx"
      }
    }
markdown
# 第八章 Redux

## 内容前瞻

本章将深入探讨 **Redux** 及其生态系统的核心概念与使用场景,涵盖以下内容:
- Redux 的基本原理与使用方式
- React-Redux 的集成与优化
- Redux 中间件的使用与实现
- 异步操作的处理(如 Redux-Thunk、Redux-Promise)
- 其他状态管理工具(如 MobX)与路由管理(如 React-Router-Dom)
- 高级工具链(如 Redux-Saga、Dva、Umi)与 UI 库(如 Ant Design Pro)

---

## Redux

### 1. **Redux 概述**
- **定义**:Redux 是一个公共状态管理方案,适用于中大体量、高频状态切换、复杂更新逻辑的场景
- **使用场景**
  - 父子组件通信:通过 `props` 或 Redux
  - 祖先与后代组件通信:通常通过 Redux
- **特性**
  - 可以在非 React 中使用,体积仅为 2KB

---

### 2. **Redux 使用步骤**

#### 1. **创建 Store 容器**
- 使用 `createStore([reducer])` 创建 Store,并规划 `reducer`
- Store 容器中存储状态和事件池;状态改变时,执行事件池中的方法

**示例**
```js
import { createStore } from 'redux';

const init = {};
const reducer = (state = init, action) => {
  const fixState = { ...state }; // 不直接修改原状态
  switch (action.type) {
    case 'TYPE_A':
      // 修改状态
      return fixState;
    default:
      return state; // 返回的信息替代公共状态
  }
};

const store = createStore(reducer);

2. 获取状态

  • 通过 store.getState() 获取当前状态

3. 订阅事件池

  • 使用 store.subscribe(func) 将事件放入事件池
  • 类组件中可以通过 forceUpdate() 强制更新视图

4. 任务分发与状态修改

  • 使用 store.dispatch({ type: 'xxx' }) 分发任务,执行 reducer 修改状态

3. Redux 机制

  • 初次派发:在 Redux 内部派发,手动 dispatch 均为二次派发之后
  • Redux 对象结构
    • @@observable
    • dispatch
    • getState
    • replaceReducer
    • subscribe

React-Redux

1. React-Redux 概述

  • 作用:将 Redux 与 React 组件绑定,简化状态管理与更新
  • 核心 API
    • Provider:将 Store 注入 React 应用
    • connect:将状态和派发方法映射到组件 props

Redux 中间件

1. 中间件概述

  • 定义:中间件是一个加工管道,通过不同的中间件实现不同的效果
  • 使用方式:通过 applyMiddleware 将中间件注入 createStore

示例

js
import { createStore, applyMiddleware } from 'redux';
import reduxLogger from 'redux-logger';

const store = createStore(reducer, applyMiddleware(reduxLogger));

2. 异步操作处理

  • 问题:Redux 的 action 方法默认不支持异步操作
  • 解决方案:使用中间件(如 Redux-Thunk、Redux-Promise)

1. Redux-Thunk

  • 原理:派发两次,第一次返回异步函数,第二次在函数内部通过重写 dispatch 派发

示例

js
function action() {
  return async (dispatch) => {
    await getData();
    dispatch({ type: 'TYPE_A' });
  };
}

2. Redux-Promise

  • 原理:内部重写 dispatch,监听 Promise 实例,状态更改后自动派发

示例

js
async function action() {
  await getData();
  return {
    type: 'TYPE_A',
  };
}

具体示例

组件中使用 Redux** 示例

jsx
import React, { useContext, useEffect, useState } from 'react';
import { StoreContext } from './store';

function Component() {
  const store = useContext(StoreContext);
  const [time, setTime] = useState(new Date());

  const handle = () => {
    console.log('Extra operation.');
  };

  useEffect(() => {
    const unsubscribe = store.subscribe(handle);
    return () => {
      unsubscribe(); // 移除订阅
    };
  }, [time]);

  useEffect(() => {
    store.subscribe(() => {
      setTime(new Date()); // 保证视图渲染与上下文最新
    });
  }, []);

  return <div>{time.toString()}</div>;
}

function SubComponent() {
  const store = useContext(StoreContext);
  const { stateExt } = store.getState();

  const handle = () => {
    store.dispatch({ type: 'TYPE_A' });
  };

  return <button onClick={handle}>Click Me</button>;
}

总结

  • Redux:适用于复杂状态管理的公共状态管理方案
  • React-Redux:简化 Redux 与 React 的集成
  • 中间件:通过中间件扩展 Redux 功能,如异步操作处理
  • 异步操作:使用 Redux-Thunk 或 Redux-Promise 处理异步任务