Redux原理解析
”只有遇到 React 实在解决不了的问题,你才需要 Redux“
Redux应用的三大原则
-
State 是只读的:唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
-
使用纯函数来执行修改:为了描述 action 如何改变 state tree ,你需要编写 reducers。
严格的单向数据流是 Redux 架构的设计核心。Redux工作流程如下:
- action通过dispatch方法会派发给store
- store接收action,连同之前的state,一起传递给reducer
- reducer返回新的state给store
- state变化重新渲染
mapStateToProps和mapDispatchToProps
React-Redux 提供connect方法,用于从 UI 组件生成容器组件
connect方法接受两个参数:mapStateToProps和mapDispatchToProps
前者负责输入逻辑,即将state映射到 UI 组件的参数(props),后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。
import { connect } from 'react-redux' import { setCustId } from '@/redux/custObj/actions' //通过props获取值和方法 const { custId } = props.custInfo useEffect(() => { // 清空数据 props.setCustId('') }, []) function mapStateToProps (state) { return { custId: state.custId } } function mapDispatchToProps (dispatch) { return { setCustId: (val) => {//传给props的方法名 dispatch(setCustId(val))//action里面的方法名 } } } export default connect(mapStateToProps, mapDispatchToProps)(OrderDetail)
Action 是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源。
Action 本质上是 JavaScript 普通对象,其中type属性是必须的,来表示将要执行的动作。代码里过大时,type可以单独提出到一个文件中。
//action-type.js //多数情况下,type 会被定义成字符串常量。 export const SET_CUST_ID = 'SET_CUST_ID' export const USER_TYPE = 'USER_TYPE'
Action 创建函数 就是生成 action 的方法
//action.js import * as type from './action-type' /*setCustId是一个函数,返回的是action对象*/ export const setCustId= (value) => { return { type: type.SET_CUST_ID, custId: value } }
Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的
reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。
注意:不要修改 state;在 default 情况下返回旧的 state
//custObj/reducer.js export const custId= (state = '', action) => { switch (action.type) { case type.SET_CUST_ID: return action.custId default: return state } }
Redux 应用只有一个单一的 store。
当需要拆分数据处理逻辑时,应该是 reducer 组合 而不是创建多个 store,使用 combineReducers() 将多个 reducer 合并成为一个对象
//store.js import { createStore, combineReducers } from 'redux' //引入不同模块的reducers import * as custObj from './custObj/reducers' import * as orderObj from './orderObj/reducers' //createStore这个函数,用来生成Store const store = createStore( combineReducers({ ...custObj, ...orderObj })) ) export default store