状态管理是当前前端框架开发当中一个很重要的点当业务或者系统复杂时,状态管理能让咱们更加清晰地了解数据的流动javascript
本文经过实现一个简单的Redux来阐述一个状态管理库的思想前端
目前前端开发框架盛行,在框架的使用过程当中就会遇到一个问题:组件间的数据通讯如何来作。简单是父子组件咱们能够经过props
来实现数据通讯,当组件层级变深,仅靠props
就不足够支撑咱们的需求,一个全局的状态管理也就变为一个迫切的需求。java
Redux只有一个Store,Store不能直接进行修改,每次操做以后都是返回一个新的对象数组
Action前端框架
Action就是View发出的通知,告诉Store 数据要改变,Action经过特定的type来知晓作何种操做闭包
const action = { type: 'plus', data: {} };
Reducer是一个纯函数,接受action和state,而后返回一个新的state。框架
总结一下,Redux的流程以下:函数
// View 发出 Action store.dispatch(action); // store 自动调用 Reducer,而且传入两个参数:当前 State 和收到的 Action。 Reducer 会返回新的 State let nextState = xxxReducer(previousState, action); // State 一旦有变化,Store 就会调用监听函数 store.subscribe(listener); // listener中能够修改组件的状态,从新渲染组件 function listerner() { let newState = store.getState(); component.setState(newState); }
状态管理,说到底就是将须要共享的数据存放在一个公共的地方,全部组件都经过它来进行数据的操做。天然而然的,咱们能够想到建立一个全局的对象来存放数据,因此先建立一个state.js
文件测试
// state.js export const state = { count: 0, }
有了数据,咱们就须要有数据的存取,以及发布订阅事件spa
所以有了如下的store.js
文件
// store.js import { state } from './state.js'; export const createStore = (reducer) => { let currentState = state; // state function getState() { // 获取state return currentState; } function dispatch() { // 设置state } function subscribe() { // 订阅事件 } return { getState, dispatch, subscribe }; }
在这里其实用到了闭包的思想
其中getState
很简单,就是获取当前的state
值
状态管理库的一个原则是不能随便修改状态的值,须要作到有条理,有标记地修改。咱们将操做单独封装在reducer.js
中,以此来保持store.js
的纯净
// reducer.js import { state as initialState } from './state.js'; export function reducer(state = initialState, action) { switch(action.type) { case 'plus': return { ...state, count: state.count + 1 }; break; case 'subtract': return { ...state, count: state.count - 1 } break; default: return initialState; } }
而后在store.js
中进行使用
// store.js import { state } from './state.js'; export const createStore = (reducer) => { let currentState = state; // state function getState() { // 获取state return currentState; } function dispatch(action) { // 设置state currentState = reducer(currentState, action); } function subscribe() { // 订阅事件 } return { getState, dispatch, subscribe }; }
状态管理库的另外一个能力就是可以经过数据改变引发视图的改变。咱们经过发布订阅模式,就能实现这一效果,经过subscribe()
来订阅事件,在dispatch()
的时候触发订阅的消息。固然真正的状态管理库中这一块确定是很复杂的,咱们这里只是简单地写个示例。
咱们经过一个数组来存放监听的事件,经过subscribe
来添加事件
// store.js import { state } from './state.js'; export const createStore = (reducer) => { let currentState = state; // state let queue = []; function getState() { // 获取state return currentState; } function dispatch(action) { // 设置state currentState = reducer(currentState, action); queue.forEach(fn => { fn(); }) } function subscribe(fn) { // 订阅事件 queue.push(fn); } return { getState, dispatch, subscribe }; }
以后添加测试用例来进行测试
import 'createStore' from './store'; const store = createStore(reducer); store.subscribe(() => { console.log('component 1') }); store.subscribe(() => { console.log('component 2') }); store.dispatch({ type: 'plus' }); store.dispatch({ type: 'plus' }); console.log(store.getState()); // component 1 // component 2 // component 1 // component 2 // { count: 2 }
这就是一个简单的Redux
的思想。