Redux
涉及内容
- redux
- react-reducx
- redux中间件
- mobx
- react-router-dom
- redux-saga dva umi
- antd pro
redux: 公共状态管理方案; 在中大体量 && 高频状态切换 && 复杂更新逻辑中使用; 父子组件一般通过props && redux 祖先 && 后代组件一般通过redux 特性
- redux可以在非react中使用, 体积仅为2kb
使用
- 创建container: createStore([reducer]) && 规划reducer
- store容器中, 存储状态 && 事件池;状态发生改变, 执行事件池中的方法;
- 获取状态(基于context获取store对象)
- store.getState()
- 放入事件到事件池(必须保证视图更新 && 上下文为最新)
- store.subscribe(func)
- 类组件传递forceUpdate()即可
- 创建容器时,传递reducer
js
const init = {}
let reducer = function reduceer(state=init, action){
// 不直接修改原状态; return时直接返回
fixState = {...state}
switch(action.type){
// 根据不同状态, 修改不同信息
...
default:
}
return state // 返回的信息替代公共状态——在第一次dispatch时, 设置初始值
}
- 任务分发, 执行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 处理异步任务