React实战-深入源码了解Redux用法之Reducers
2016-09-12 22:34
871 查看
React实战-深入源码了解Redux用法之Reducers
在Redux中Reducers是真正实现state数据变化的工作。我们在使用Redux时,可能也只是似懂非懂,我们不知道它是如何工作的,我们知道在Action中定义事件,在Reducers中定义对应事件对应的操作,我们知道他们有关系,但如何建立的关系不知道(微信:react-javascript)。
1.Flux中事件的定义
还是看看Flux中是如何定义的吧,在Flux中,事件流是非常清楚的。
a.我们定义Action
module.exports = {
deletePersonByID: function(id) {
AccountDispatcher.dispatch({
type: ActionTypes.DELETE_PERSON,
id: id
});
}
}
b.在store中定义事件和action对于的操作
定义事件:var CHANGE_EVENT = 'change';
定义事件绑定与解绑定:
addChangedListener(callback)
{
this.on(CHANGE_EVENT, callback);
},
removeChangedListener(callback){
this.removeListener(CHANGE_EVENT, callback);
}
定义事件对应的操作:
PersonDispatcher.register(function (action) {
switch (action.type) {
case ActionTypes.DELETE_PERSON:
PersonStore.deleteByID(action.id);
break;
}
}
c.在comonent中关联事件:
componentDidMount(){
PersonStore.addChangedListener(this._onChange);
},
componentWillUnmount(){
PersonStore.removeChangedListener(this._onChange);
},
整个过程清楚明了。
2.Redux中却少了很多环节
a.定义Action,基本与Flux相同
b.定义reducers:我们常常看到的例子是这样的
export default function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
或者是类似的变种吧。
3.Reducers源码分析
现在问题来了背后的数据流到底是如何产生的?还是看看源码吧。
export default function combineReducers(reducers) {
var reducerKeys = Object.keys(reducers)
var finalReducers = {}
for (var i = 0; i < reducerKeys.length; i++) {
var key = reducerKeys[i]
.......
return function combination(state = {}, action) {
...........
var hasChanged = false
var nextState = {}
for (var i = 0; i < finalReducerKeys.length; i++) {
var key = finalReducerKeys[i]
var reducer = finalReducers[key]
var previousStateForKey = state[key]
var nextStateForKey = reducer(previousStateForKey, action)
if (typeof nextStateForKey === 'undefined') {
var errorMessage = getUndefinedStateErrorMessage(key, action)
throw new Error(errorMessage)
}
nextState[key] = nextStateForKey
hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}
return hasChanged ? nextState : state
}
}
}
从源码中我们可以看到:在Redux中为了方便统一管理,省去了事件的绑定与解绑定,将事件作为事件队列进行统一管理。
var reducerKeys = Object.keys(reducers)
var finalReducers = {}
for (var i = 0; i < reducerKeys.length; i++) {
var key = reducerKeys[i]
.....
}
每次执行一个事件操作时,并不仅仅只执行这个事件,而是会将事件队列中的所有事件进行遍历。
for (var i = 0; i < finalReducerKeys.length; i++) {
......
}
在每次遍历时都在同一state上构建数据树,同时在遍历时会判断本事件是否导致了整个state数据树的数据变化。
hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}
return hasChanged ? nextState : state
......
}
看到这里是否清楚了?好像还是没有,Redux中的事件与数据流的管理,并不只是由一个函数完成的,而是由reducers、connect等多个函数共同完成,然而如此做法,对性能影响是否很大,这还得进一步查看相关代码才能解惑。
在Redux中Reducers是真正实现state数据变化的工作。我们在使用Redux时,可能也只是似懂非懂,我们不知道它是如何工作的,我们知道在Action中定义事件,在Reducers中定义对应事件对应的操作,我们知道他们有关系,但如何建立的关系不知道(微信:react-javascript)。
1.Flux中事件的定义
还是看看Flux中是如何定义的吧,在Flux中,事件流是非常清楚的。
a.我们定义Action
module.exports = {
deletePersonByID: function(id) {
AccountDispatcher.dispatch({
type: ActionTypes.DELETE_PERSON,
id: id
});
}
}
b.在store中定义事件和action对于的操作
定义事件:var CHANGE_EVENT = 'change';
定义事件绑定与解绑定:
addChangedListener(callback)
{
this.on(CHANGE_EVENT, callback);
},
removeChangedListener(callback){
this.removeListener(CHANGE_EVENT, callback);
}
定义事件对应的操作:
PersonDispatcher.register(function (action) {
switch (action.type) {
case ActionTypes.DELETE_PERSON:
PersonStore.deleteByID(action.id);
break;
}
}
c.在comonent中关联事件:
componentDidMount(){
PersonStore.addChangedListener(this._onChange);
},
componentWillUnmount(){
PersonStore.removeChangedListener(this._onChange);
},
整个过程清楚明了。
2.Redux中却少了很多环节
a.定义Action,基本与Flux相同
b.定义reducers:我们常常看到的例子是这样的
export default function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
或者是类似的变种吧。
3.Reducers源码分析
现在问题来了背后的数据流到底是如何产生的?还是看看源码吧。
export default function combineReducers(reducers) {
var reducerKeys = Object.keys(reducers)
var finalReducers = {}
for (var i = 0; i < reducerKeys.length; i++) {
var key = reducerKeys[i]
.......
return function combination(state = {}, action) {
...........
var hasChanged = false
var nextState = {}
for (var i = 0; i < finalReducerKeys.length; i++) {
var key = finalReducerKeys[i]
var reducer = finalReducers[key]
var previousStateForKey = state[key]
var nextStateForKey = reducer(previousStateForKey, action)
if (typeof nextStateForKey === 'undefined') {
var errorMessage = getUndefinedStateErrorMessage(key, action)
throw new Error(errorMessage)
}
nextState[key] = nextStateForKey
hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}
return hasChanged ? nextState : state
}
}
}
从源码中我们可以看到:在Redux中为了方便统一管理,省去了事件的绑定与解绑定,将事件作为事件队列进行统一管理。
var reducerKeys = Object.keys(reducers)
var finalReducers = {}
for (var i = 0; i < reducerKeys.length; i++) {
var key = reducerKeys[i]
.....
}
每次执行一个事件操作时,并不仅仅只执行这个事件,而是会将事件队列中的所有事件进行遍历。
for (var i = 0; i < finalReducerKeys.length; i++) {
......
}
在每次遍历时都在同一state上构建数据树,同时在遍历时会判断本事件是否导致了整个state数据树的数据变化。
hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}
return hasChanged ? nextState : state
......
}
看到这里是否清楚了?好像还是没有,Redux中的事件与数据流的管理,并不只是由一个函数完成的,而是由reducers、connect等多个函数共同完成,然而如此做法,对性能影响是否很大,这还得进一步查看相关代码才能解惑。
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 设计模式---状态模式在web前端中的应用
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- 00