写一个迷你Redux
这是一篇翻译文章,通过写一个迷你版Redux来学习Redux。不过我不会依字翻译,老外话太多。
网上有很多Redux学习资料,官方文档、示例、博客等等,但对于新手依然会感到糊涂……本文要给大家一个不同的学习方式,来写一个Redux。看起来很难是吧?其实很简单。
Redux是什么货?它是做啥子的……
Redux是统一管理你的状态的,所有的状态都以js object存于一个地方:即store中。state是只读的,如果你想改变状态,需要发起一个Action,所谓的Action也就只是一个js对象。当状态变化了后,你的应用程序会收到通知。当Redux和React一起用的时候,状态变了,React组件会收到通知,然后根据新的数据来重新渲染组件。
redux.png
不过,store在收到一个Action后,需要知道怎么更新状态。这时又会用到一个js函数,也就是Reducer。当Store创建的时候,会传入这些Reducer。说完这些,下面我们开始动手吧。
撸码
总结一下,store需要做三件事
- 获取当前状态
- 发起一个动作,传入到reducer中来更新store中的状态
- 监听store的变化
在最开始,要定义一个reducer和初始的state,然后创建store,如下:
function createStore(reducer, initialState) {
var currentReducer = reducer;
var currentState = initialState;
}
- 获取状态
现在这个函数把reducer和initialState都保存了一份局部变量,现在实现获取状态,如下 :
function createStore(reducer, initialState) {
var currentReducer = reducer;
var currentState = initialState;
return {
getState() {
return currentState;
}
};
}
Yes, 获取状态就是这么简单!
- Dispatch一个Action
下面就是让store支持发起一个Action
function createStore(reducer, initialState) {
var currentReducer = reducer;
var currentState = initialState;
return {
getState() {
return currentState;
},
dispatch(action) {
currentState = currentReducer(currentState, action);
return action;
}
};
}
dispatch把当前状态及action传给了reducer,reducer会更新状态。
- 监听状态变化
现在已经实现获取当前状态,更新状态功能!下一步是实现监听状态改变。如下:
function createStore(reducer, initialState) {
var currentReducer = reducer;
var currentState = initialState;
var listener = () => {};
return {
getState() {
return currentState;
},
dispatch(action) {
currentState = currentReducer(currentState, action);
listener(); // 注意这行!
return action;
},
subscribe(newListener) {
listener = newListener;
}
};
}
我们定义了一个subscribe函数,里面传入一个参数是回调函数。当dispatch一个action后,我们会调用这个回调函数。
搞定!来用吧!
以上就是一个mini版redux实现,实际上是redux的精简版。在Redux官方github页面上,有一个示例,我们用来测试一下我们写的这个。
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
let store = createStore(counter)
store.subscribe(() =>
console.log(store.getState())
)
store.dispatch({ type: 'INCREMENT' })
store.dispatch({ type: 'INCREMENT' })
store.dispatch({ type: 'DECREMENT' })
完整的代码在这 <a href="https://gist.github.com/jakoblind/6b90d0b677d26effcebbed69b24cb05f">完整代码</a>
总结
我们用18行代码实现了一个可用的Redux,哇!当然这个代码很明显不适合生产环境,和真正的redux比,还缺少错误处理,不支持多个监听器,不支持middleware(中间件)等等。
但你已经知道Redux的基本原理了,Happy coding,接着撸码吧~
关注我:
极客学社<a href="http://blog.jakoblind.no/2017/03/13/learn-redux-by-coding-a-mini-redux/">原文链接</a>