我们用上面的状态管理器来实现一个自增,自减的计数器。

    1. let initState = {
    2. count: 0
    3. }
    4. let store = createStore(initState);
    5. store.subscribe(() => {
    6. let state = store.getState();
    7. console.log(state.count);
    8. });
    9. /*自增*/
    10. store.changeState({
    11. count: store.getState().count + 1
    12. });
    13. /*自减*/
    14. store.changeState({
    15. count: store.getState().count - 1
    16. });
    17. /*我想随便改*/
    18. store.changeState({
    19. count: 'abc'
    20. });

    你一定发现了问题,count 被改成了字符串 abc,因为我们对 count 的修改没有任何约束,任何地方,任何人都可以修改。

    我们需要约束,不允许计划外的 count 修改,我们只允许 count 自增和自减两种改变方式!

    那我们分两步来解决这个问题

    1. 制定一个 state 修改计划,告诉 store,我的修改计划是什么。

    2. 修改 store.changeState 方法,告诉它修改 state 的时候,按照我们的计划修改。

    我们来设置一个 plan 函数,接收现在的 state,和一个 action,返回经过改变后的新的 state。

    1. /*注意:action = {type:'',other:''}, action 必须有一个 type 属性*/
    2. function plan(state, action) {
    3. switch (action.type) {
    4. case 'INCREMENT':
    5. return {
    6. ...state,
    7. count: state.count + 1
    8. }
    9. case 'DECREMENT':
    10. return {
    11. ...state,
    12. count: state.count - 1
    13. }
    14. default:
    15. return state;
    16. }
    17. }

    我们把这个计划告诉 store,store.changeState 以后改变 state 要按照我的计划来改。

    1. /*增加一个参数 plan*/
    2. const createStore = function (plan, initState) {
    3. let state = initState;
    4. let listeners = [];
    5. function subscribe(listener) {
    6. listeners.push(listener);
    7. }
    8. function changeState(action) {
    9. /*请按照我的计划修改 state*/
    10. state = plan(state, action);
    11. for (let i = 0; i < listeners.length; i++) {
    12. const listener = listeners[i];
    13. listener();
    14. }
    15. }
    16. function getState() {
    17. return state;
    18. }
    19. return {
    20. subscribe,
    21. changeState,
    22. getState
    23. }
    24. }

    我们来尝试使用下新的 createStore 来实现自增和自减

    1. let initState = {
    2. count: 0
    3. }
    4. /*把plan函数*/
    5. let store = createStore(plan, initState);
    6. store.subscribe(() => {
    7. let state = store.getState();
    8. console.log(state.count);
    9. });
    10. /*自增*/
    11. store.changeState({
    12. type: 'INCREMENT'
    13. });
    14. /*自减*/
    15. store.changeState({
    16. type: 'DECREMENT'
    17. });
    18. /*我想随便改 计划外的修改是无效的!*/
    19. store.changeState({
    20. count: 'abc'
    21. });

    到这里为止,我们已经实现了一个有计划的状态管理器!

    我们商量一下吧?我们给 plan 和 changeState 改下名字好不好?plan 改成 reducer,changeState 改成 dispatch!不管你同不同意,我都要换,因为新名字比较厉害(其实因为 redux 是这么叫的)!

    本小节完整源码见 demo-2