redux状态传播

Redux三大概念

Redux 是JavaScript状态容器,提供可预测化的状态管理

action 普通的JS对象描述发生什么

reducer 只是一个接收 state 和 action,并返回新的 state 的函数

Store — 数据存储中心,同时连接着Actions和Views(React Components)。

  1. Store需要负责接收Views传来的Action
  2. 然后,根据Action.type和Action.payload对Store里的数据进行修改
  3. 最后,Store还需要通知Views,数据有改变,Views便去获取最新的Store数据,通过setState进行重新渲染组件(re-render)。

三大原则

  1. 单一数据源

整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。和根级的reducer,拆成多个reducer而不是多个store。

  1. State 是只读的

唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。

  1. 使用纯函数来执行修改

为了描述 action 如何改变 state tree ,你需要编写 reducers。传递数据 payload规范。

当 state 变化时需要返回全新的对象,而不是修改传入的参数。


api

// API 是 { subscribe, dispatch, getState }。
let store = createStore(counter);

// 可以手动订阅更新,也可以事件绑定到视图层。
store.subscribe(() =>
  console.log(store.getState())
);

// 改变内部 state 唯一方法是 dispatch 一个 action。
// action 可以被序列化,用日记记录和储存下来,后期还可以以回放的方式执行
store.dispatch({ type: 'INCREMENT' });
// 1
store.dispatch({ type: 'INCREMENT' });
// 2
store.dispatch({ type: 'DECREMENT' });
// 1

不要再reducer里做以下操作保持纯净

修改传入参数;

执行有副作用的操作,如 API 请求和路由跳转;

调用非纯函数,如 Date.now() 或 Math.random()。

通过reducer修改数据带来的好处

  1. 数据拆解 => 通过定义多个reducerr对数据进行拆解访问或者修改,最终再通过combineReducers函数将零散的数据拼装回去。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { combineReducers } from 'redux';

// 叶子reducer
function aReducer(state = 1, action) {/*...*/}
function cReducer(state = true, action) {/*...*/}
function eReducer(state = [2, 3], action) {/*...*/}

const dReducer = combineReducers({
e: eReducer
});

const bReducer = combineReducers({
c: cReducer,
d: dReducer
});

// 根reducer
const rootReducer = combineReducers({
a: aReducer,
b: bReducer
});
  1. 数据不可变 组件的生命周期函数shouldComponentUpdate进行判断是否有必要进行对该组件进行更新(即,是否执行该组件render方法以及进行diff计算)

维持应用的 state

提供 getState() 方法获取 state;

提供 dispatch(action) 方法更新 state;发送通知;

通过 subscribe(listener) 注册监听器;

通过 unsubscribe() 返回的函数注销监听器。

纯函数是这样一种函数,即相同的输入,永远会得到相同的输出。 store.dispatch方法会触发 Reducer 的自动执行。为此,Store 需要知道 Reducer 函数,做法就是在生成 Store 的时候,将 Reducer 传入createStore方法。

中间件提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。

1
2
3
4
5
6
7
8
9
10
11
12
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import createLogger from 'redux-logger';
import rootReducer from '../reducers';

// store扩展
const enhancer = applyMiddleware(
thunk,
createLogger()
);

const store = createStore(rootReducer, initialState, enhancer);

react-redux

Redux 本身和React没有关系,只是数据处理中心,是React-Redux让它们联系在一起。

React-Redux提供两个方法:connect和Provider。

connect

connect连接React组件和Redux store。connect实际上是一个高阶函数,返回一个新的已与 Redux store 连接的组件类。

1
2
3
4
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)

TodoList是 UI 组件,VisibleTodoList就是由 react-redux 通过connect方法自动生成的容器组件。

mapStateToProps:从Redux状态树中提取需要的部分作为props传递给当前的组件。 mapDispatchToProps:将需要绑定的响应事件(action)作为props传递到组件上。

Provide(将 store 通过 context 传入组件中)

Provider实现store的全局访问,将store传给每个组件。 原理:使用React的context,context可以实现跨组件之间的传递。

reducer的拆分和重构

随着项目越大,如果将所有状态的 reducer 全部写在一个函数中,将会 难以维护;可以将 reducer 进行拆分,也就是 函数分解,最终再使用combineReducers()进行重构合并;

异步Action

由于 Reducer 是一个严格的纯函数,因此无法在 Reducer 中进行数据的请求,需要先获取数据,再dispatch(Action)即可,下面是三种不同的异步实现:

使用 复杂性 数据交互 结构复杂繁琐 大型

  • “如果你不知道是否需要 Redux,那就是不需要它。”
  • “只有遇到 React 实在解决不了的问题,你才需要 Redux。”
本文结束感谢您的阅读

本文标题:redux状态传播

文章作者:陈宇(cosyer)

发布时间:2018年06月21日 - 19:06

最后更新:2020年06月02日 - 23:06

原始链接:http://mydearest.cn/reduxstate.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持原创技术分享,您的支持将鼓励我继续创作!