redux爬坑记

来源:互联网 发布:stl格式是什么软件 编辑:程序博客网 时间:2024/06/05 11:40

参考 http://www.w3ctech.com/topic/1561
[http://www.tuicool.com/articles/vEnMFzz](这篇文章也不错源码注释挺清楚 帮助理解)
redux相比于Reflux和flux更像。

redux分为三部分:
actions, reducers, store

actions: 用来描述动作行为的,向store发送命令。例:

eat= (food) => {type: eat,food}

actions只是用来描述吃这个行为,必须有一个type来标识这个行为的类型,要改变store交给reducers
reducers:用来修改store的状态。reducer 就是一个纯函数,接收旧的 state(全局的) 和 action,返回新的 state。传入两个参数。例:

reducer = (state, action) =>{    switch (action.type) {        case EAT:            return action.food        default:              //一定要有            return state;    }}

var rootReducer = combineReducer(reducer);
rootReducer总是返回新的state,不修改旧state,而是创建空对象,然后将 key/value 往上面挂载。只有在 reducers 对象上的 key 才会被迁移。
上面提到的 action 跟 reducer 函数,都是普通的纯函数。对于 action 函数 来说,输入相同的参数无限次,它的返回值也相同。而有了「不变值」,我们得到的好处是,在 react component 的 shouldComponentUpdate(nextProps, nextState) 里,可以直接拿当前 props 跟 nextProps 做 === 对比,如果相等,说明不用更新,如果不相等,则更新到视图。

如果不是返回新 state,只是修改旧 state,我们就很难做到「回退/撤销」以及跟踪全局状态。对比两个数据是否同一,也无法用 === ,而得用 deepEqual 深度遍历来对比值,很耗费性能。
store:代表的是数据模型,内部维护了一个state变量,用力描述应用的状态。
store有几个重要的方法:

let store = createStore(rootReducers, initialState);

getState:获取应用当前state
dispatch(action):分发action。修改state
而 dispatch 方法,是 store 对象提供的更改 currentState 这个闭包变量的唯一建议途径。注意,我是说唯一建议,不是说唯一途径,因为 getSate 拿到的是 currentState 的对象引用,我们还是可以在外头改动它,虽然不建议。
subscribe:监听action变化
replaceReducer:替换store当前用来处理state的reducer

常用的是dispatch,这是修改state的唯一途径

store.dispatch(eat('beef'));//dispatch部分源码function dispatch(action) {  // currentReducer 是当前的Reducer  function dispatch(action) {  // currentReducer 是当前的Reducer  currentState = currentReducer(currentState, action);listeners.slice().forEach(function (listener) {    return listener();  });return action;}

关于Redux中的state:
State其实一直在Redux内部保存着。并且每次执行currentReducer都会更新。在上面代码第一行可以看到。
currentState = currentReducer(currentState, action);
注:个人理解是从reducer中获取的,在定义reducer的时候会传两个参数(state, action).

那redux整体流程就是:(编不下去了 捂脸)
我想吃东西(action),想吃beef:store.dispatch(eat(‘beef’));
通知服务员(reducer),服务员根据你是吃东西(type:EAT)往菜单上记你想吃的菜、餐桌号等 (return{action.food,…state})
服务员通知后厨做牛肉并生成订单(修改state):我几号桌,想吃牛肉。

下面是重头戏:react-redux
关键词:Provider、connect、mapStateToProps、mapDispatchToProps

mapStateToProps:筛选state,返回给component。

mapStateToProps(state) => {    return eat:state.eat}

mapDispatchToProps:把action放到props上
当它被connect调用的时候会为它传递一个参数dispatch。

mapDispatchToProps负责返回一个 dispatchProps
dispatchProps 是actionCreator的key和dispatch(action)的组合。

dispatchProps 看起来长这样:

{  addItem: (text) => dispatch(action)}

connect 收到这样的数据后,会把它放到React组件上。然后子组件就可以通过props拿到addItem并且使用啦。

this.props.addItem('Hello World~');

如果觉得复杂,不好理解,,那我用大白话描述一下

就是通过mapDispatchToProps这个方法,把actionCreator变成方法赋值到props,每当调用这个方法,就会更新State。。。。额,,这么说应该好理解了。。

bindActionCreators:将Actions 和 dispatch 组合起来生成 mapDispatchToProps 需要生成的内容。

function mapDispatchToProps(dispatch) {  return {    actions: bindActionCreators(createActions, dispatch)  }}

connect: export default connect(mapStateToProps, mapDispatchToProps)(Componnet)
两个变量的参数是store传的,store为什么能传这么远是因为Provider。
将筛选粗来的state和 action作为props添加到Component上。

Provider
Provider是一个React组件,它的作用是保存store给子组件中的connect使用。

通过getChildContext方法把store保存到context里。
后面connect中会通过context读取store。
它看起来是这个样子的:

<Provider store={this.props.store}>  <h1>Hello World!</h1></Provider>

这是一部分核心源码:

getChildContext() {  return { store: this.store }}constructor(props, context) {  super(props, context)  this.store = props.store}

可以看到,先获取store,然后用 getChildContext 把store保存起来~

redux工作流程
actionCreator|reducer|combineReducers|createStore|bindActionCreators

设计全局 state 的数据结构
设计更改 state 数据的 actionTypes 常量以及其他跟视图展现相关的 actionTypes 常量
根据 actionTypes 常量,书写 actionCreator 。
根据各个 actionCreator 的返回值,涉及 reducer 做数据的最后处理
在有了 reducer 函数之后,createStore(reducer, initState) 得到 store 对象
用 bindActionCreators 函数将 actionCreators 和 store.dispatch 绑定起来,得到一组能修改全局状态的函数
分发各个状态修改函数到各个 DOM 事件中。

0 0
原创粉丝点击