一、Redux 核心
官方是这样解释Redux的:JavaScript 状态容器,提供可预测化的状态管理。
const state = {
modleOpen: "yes",
btnClicked: "no",
btnActiveClass: "active",
page: 5,
size: 10
}
- Redux 核心概念及工作流程
- store: 存储状态的容器,JavaScript对象
- View: 视图,HTML页面
- Actions: 对象,描述对状态进行怎样的操作
- Reducers: 函数,操作状态并返回新的状态
Redux 计数器案例 ../Redux/src/counter
0
- Redux核心API
const store = Redux.crateStore(reducer)
: 创建 Store 容器function reducer (state = initialState, action) {}
: 创建用于处理状态的 reducer 函数store.getState()
: 获取状态store.subscribe(function(){})
: 订阅状态store.dispatch({type: 'discription...'})
: 触发action
二、React + Redux
1.在 React 中不使用 Redux 时遇到的问题
在 React 中组件通信的数据流是单向的,顶层组件可以通过props属性向下层组件传递数据,而下层组件不能向上层组件传递数据,要实现下层组件修改数据,需要
上层组件传递修改数据方法到下层组件,当项目越来越大的时候,组件之间传递数据也就变得越来越困难。
2.在 React 项目中引入 Redux 的好处
使用Redux管理数据,由于Store独立于组件,使得数据管理独立于组件,解决了组件与组件之间传递数据困难的问题。
3.下载Redux
npm install redux react-redux
4.Redux 工作流程
- 组件通过 dispatch 方法触发 action
- Store 接收 Action 并将 Action 分发给 Reducer
- Reducer 根据 Action 类型对状态进行更改并将更改后的状态返回给Store
- 组件订阅了Store中的状态,Store中的状态更新会同步到组件
5.代码案例
计数器案例 ../Redux/react-redux-guide/src/components/Counter.js
弹出框案例 ../Redux/react-redux-guide/src/components/Modal.js
6.拆分Reducer
../Redux/react-redux-guide/src/react-redux-guide/src/store/reducers/root.reducer.js
三、Redux 中间件
中间件本质上就是一个函数,Redux允许我们通过中间件的方式,扩展和增强Redux应用程序,增强体现在对action处理能力上,之前的计数器与弹出框案例中。actions都是直接被reducer函数处理的,再加入了中间件以后,在出发了一个action之后这个action会优先被中间件处理,当中间处理完这个action以后,中间件会把这个action传递给reducer,让reducer继续处理
1.开发Redux中间件
开发中间件模版代码,本质上是一个函数,并且是一个柯里化的一个函数
export default store => next => action => {}
这个函数中要求我们返回一个函数,在这个返回的函数中要求我们再返回一个函数,在最里层的函数中我们可以执行我们自己的业务逻辑,在最外层的函数中给我们提供了一个参数叫store,可以用store.getState获取当前state状态,也可以使用store.dispatch来触发另外一个action,至于干什么具体根据使用的业务逻辑来决定。在最里层的函数也有一个形参,这个形参就是组件触发的action对象,可以根据action.type来决定是否对当前action进行处理。中间的函数也有一个参数,这个参数是一个函数,我们称之为next,在我们执行完了逻辑代码之后,我们要去调用next方法,把当前action 传递给reducer,或者说传递给下一个中间件,因为中间件可以有多个。中间件开发好之后需要引入我们写的中间件并且注册给redux。
2.注册中间件
中间件在开发完成以后只有被注册才能在Redux的工作流程中生效。
import { createStore, applyMiddleware } from 'redux'
import logger from './middlewares/logger'
createStore(reducer, applyMiddleware(
logger
))
代码案例:src/react-redux-guide/src/store/middleware
/**
* src/react-redux-guide/src/store/middleware/logger.js
* 开发中间件
* 中间件模板代码 export default store => next => action => {}
*/
export default store => next => action => {
console.log(action);
console.log(store);
next(action); // 只有调用了next方法才可以将action传递给下一个中间件或者reducer
}
/**
* src/react-redux-guide/src/index.js
*/
import { createStore, applyMiddleware } from 'redux';
import RootReducer from "./reducers/root.reducer";
import logger from "./middleware/logger";
import test from "./middleware/test";
// 注册中间件 applyMiddleware(logger); 中间件的执行顺序取决去注册的顺序
export default createStore(RootReducer, applyMiddleware(logger, test));
中间件通用性改造
/** * src/react-redux-guide/src/store/middleware/thunk.js */ import actionTypes from "../actionTypes"; export default store => next => action => { // if(action.type === actionTypes.countIncrementType || action.type === actionTypes.countDecrementType) { // // 开启延迟操作 // setTimeout(() => { // next(action); // },2000) // } // 1.当这个中间件函数不关心你想执行什么异步操作,只关心你执行的是不是异步操作 // 2.如果你执行的是异步操作,再你触发action的时候,给中间件传递一个函数,如果执行的是同步操作就传递一个正常action对象 // 3.异步操作代码要写在传递进来的函数中 // 4.当前这个中间件的函数在点用你传递进来的函数时,要将dispatch方法传递进去 if(typeof action === 'function') { return action(store.dispatch); } next(action); }