2018-07-12 11:02
#React #Redux #ES6使用 React 全家桶系列已经有一段时间了,从刚开始的不知所措到现在的
熟练粘贴
得心应手,我学到最有价值的一件事就是保持好奇与思考。当引入一个新技术时,不只是被动接受与使用,更重要的是想一想,为什么要使用这个技术,使用它会带来什么好处与缺点。涉及到今天的主角
Redux,就需要思考为什么使用它,使用 Redux 的利弊是什么。
学习新知识点,概念很重要。你也许会从各种各样的 React 教程中得知了我们主角(Redux)的大名,然而它很委屈,Redux 大声嚷道:“我和 React 没什么关系,我们之间的关系就如同 Java 与 JavaScript 之间的关系一样。” Redux 只是一个可预测的状态容器,只不过经常和 React 搭配使用,所以才会出现在一些 React 的文档和教程中。
明确了 Redux 是什么,接下来的问题是要不要使用它。其实当你问出这个问题时,你可能很大程度上并不需要使用它。Redux 就像吃饭时用的勺子一样,当你要喝汤的时候,自然而然会使用勺子。当你的 Web 应用状态十分复杂甚至让你觉得有些混乱时,Redux 就是你的好帮手。
Redux 是一种发布/订阅者模式,核心思想是单向数据流,简单的描述就是:用户操作或者与后端交互数据触发 Action —> Reducer 更新状态 —> 订阅者组件根据新状态更新界面,使用 Redux,就是在不停地重复上面的步骤。由此思想,Redux 有以下的准则:
Redux 的使用同样非常简单,这里我们可以试着实现一些核心的
API,来深入学习 Redux。Redux API 的核心是 Store,Redux 通过 Store
管理应用的状态。createStore
方法实现如下,从名字就可以看出来,这个方法创建应用唯一的 Store。
const createStore = (reducer, initialState) => {
const store = {};
.state = initialState;
store.getState = () => store.state;
store...
return store;
}
上面就是创建 Store 的基本代码,但是别忘了,还需要实现发布/订阅者模式。
.listeners = [];
store
.subscribe = (listener) => {
store.listeners.push(listener);
store;
}
.dispatch = (action) => {
store.state = reducer(store.state, action);
store.listeners.forEach(listener => listener());
store; }
上面的方法中引入了 Reducer, 这里是我们真正操作数据的地方。
const reducer = (prevState, action) => {
let nextState = {};
...
return nextState;
; }
学习 Reducer,可以类比 JS
数组操作中的reduce
方法,Reducer
会对上一个状态(prevState)应用
action,然后返回新的状态(nextState)。
说到这里,Redux 核心的 API 已经完成了,你也许觉得不可思议,但 Redux 就是这么简单,非常直白,没有任何“黑魔法”,这也是我喜欢它的地方。
现在,我们可以使用自己实现的 Redux 来写一个 Demo 了。这个 Demo 是个自增的计数器,界面就是普通的 HTML 页面(再一次提醒 Redux 并不一定要搭配 React 才能使用)。
<span class="countor"></span>
<script>
const dom = document.querySelector('.countor');
</script>
准备创建 Store 所需的 reducer 与 state。
const state = {
count: 0
;
}
const reducer = (state, action) => {
switch(action.type) {
case 'ADD':
return {
count : state.count + 1
}
default:
return state;
}; }
创建 Store,监听界面变化并初始化应用,在用户点击计数器时触发 Action,至此此所有代码完毕。
const store = createStore(reducer, state);
.subscribe(() => {
storeconst state = store.getState();
.innerHTML = state.count;
dom;
})
// init
.dispatch({});
store
// action
.addEventListener('click', () => {
dom.dispatch({
storetype: 'ADD',
payload: ''
;
}); })
追求最新的技术并没有错,但是要记得拨开新技术的迷雾,看到它传递的思想。通过 Redux,我了解到如何把函数式编程融入到实际的开发之中。以前我觉得函数式编程是一种“飘在空中”的编程范式,现在看来,它是如此频繁地出现在我们周围,切切实实地帮助我们提升了开发效率。感谢 Redux,感谢开源社区。