redux的 combineReducers 和 createStore 的实现原理

最近一直在学习 redux, 感到了深深的难过,都两天了,感觉还是不知道怎么写代码,倒不是不知道是Redux 里面涉及的概念,是不知道什么代码该放在哪里。怎么样组织结构。希望再过两天能更清晰。

Redux 中 combineReducers 和 createStore的实现原理

下面是中间学习到的 combineReducers 和 createStore 的实现原理,了解这些后,确实帮助了我更好的理解整个流程。

combineReducers 的实现原理

在探究 combineReducers 的实现原理之前,先看下 combineReducers 的用法:

const todoApp = combineReducers({
visibilityFilter,
todos
});

这里为了逻辑上的分离,我们把 reducers 拆分成了 visibilityFilter 和 todos , 然后利用了 combineReducers 合成了一个 reducer 。

先看下我们的 todos 和 visibilityFilter 是这样的:

//todos 
const todos = (state = [], action) => {
switch (action.type) {
case 'ADD_TODO':
//...
case 'TOGGLE_TODO':
//...
default:
return state
}
}

//visibilityFilter
const visibilityFilter = (state = 'SHOW_ALL', action) => {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter
default:
return state
}
}

我们的 reducers 也是跟这里的每一个分 reducer 一样,都是函数,都要通过传入 (state, action) 来唯一判断下次的状态。所以我们 combineReducers 的作用就是重新生成一个 可以传入 (state, action) 两个值来判断 next 的 state 的值的函数。

所以这下我们就可以理解下面的代码, combineReducers 的实现:

const combineReducers = ( reducers ) => {
return ( state = {}, action ) => {
return Object.keys(reducers).reduce(
( nextState, key ) => {
nextState[key] = reducers[key](
state[key],
action
);
return nextState;
},
{}
);
};
};

export default combineReducers;

解释下:首先是返回一个可以传入两个参数的函数。所以我们先 return 一个 function, 然后再通过 reduce 函数,遍历每一个 key 值, 然后为对应的 state 赋值为新的函数。
其中Object.key()方法:
Object.keys() 方法会返回一个由给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 (两者的主要区别是 一个 for-in 循环还会枚举其原型链上的属性)。
Object.key(reduces)会把reduces转成数组。如下
(["visibilityFilter", "todos"])

再用reduce方法遍历数组中的元素把对应的数据组装好。
var state=[];
var action=[];
var todos = (state = {id:"tangzhl",age:"18"}
, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return action.filter
    case 'TOGGLE_TODO':
    //...
    default:
      return state
  }
}
//visibilityFilter
var visibilityFilter = (state = 'SHOW_ALL', action) => {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}
var todoApp = {
    visibilityFilter,
    todos
};
// todoApp
console.log(Object.keys(todoApp));
let sdf = Object.keys(todoApp).reduce(
function ss(nextState,key){
//在对象中添加对应的state和action
nextState[key] = todoApp[key](
state[key],
action
);
return nextState;
},{}
)
console.log(sdf);

当我们形成了新的 reducer 以后, 传入任何 的 action 和 status 就会返回一个明确的 状态树了。可能是下面这个样子的:

{
visibilityFilter: 'SHOW_ALL',
todos: {
id: 0,
text: 'Hello world',
completed: false
}
}

createStore 的实现原理

同样我们先看下 createStore 的用法:

//let { subscribe, dispatch, getState } = createStore(reducer);
import { createStore } from 'redux';
const store = createStore(reducer)

createStore 通过传入 我们的 reducer 形成一个全局唯一的 store, 这个形成的 store 是一个对象,它有3个方法,分别是:

store.dispatch()
store.subscribe()
store.getState()

所以其实我们就是要编辑一个函数,这个函数里面可以有这三个方法暴露给我们使用。原理如下:

const createStore = ( reducer ) => {
let state;
let listeners = [];

const getState = () => state;

const dispatch = ( action ) => {
state = reducer(state, action);
listeners.forEach(listener => listener());
}

const subscribe = ( listener ) => {
listeners.push(listener);
return ()=>{
listeners = listeners.filter(l => l !== listener)
}
}

dispatch({});

return {
getState,
dispatch,
subscribe
}
}

可以看到我们是先实现了这三个方法。下面简单看下怎么用这三个方法:

const {createStore} = Redux;
const store = createStore(reducer);

const render = () => {
document.body.innerHTML = store.getState();
}

store.subscribe(render)

render();
document.addEventListener('click', ()=>{
store.dispatch({type:'INCREMENT'});
})

NO COMMENTS
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值