您的位置:首页 > 其它

redux爬坑记

2016-05-17 14:16 253 查看
参考 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 事件中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Redux