你能手写个简单的 redux 吗?

Redux 本身就是一个单纯的状态机,Store存放了所有的状态,Action是一个改变状态的通知,Reducer接收到通知就更改Store中对应的状态

redux例子

import { createStore } from 'redux';

const initState = {
  milk: 0
};

function reducer(state = initState, action) {
  switch (action.type) {
    case 'PUT_MILK':
      return {...state, milk: state.milk + action.count};
    case 'TAKE_MILK':
      return {...state, milk: state.milk - action.count};
    default:
      return state;
  }
}

let store = createStore(reducer);

// subscribe 订阅store的变化,一旦store发生了变化,传入的回调函数就会被调用
store.subscribe(() => console.log(store.getState()));

// 将action发出去要用dispatch
store.dispatch({ type: 'PUT_MILK',count: 1 });    // milk: 1
store.dispatch({ type: 'PUT_MILK',count: 1 });    // milk: 2
store.dispatch({ type: 'TAKE_MILK',count: 1 });   // milk: 1
复制代码

自己实现

  1. createStore: 接收的第一个参数是reducer,需要返回getStatedispatchsubscribe等方法
  2. getState: 返回当前的state
  3. reducer: 接收stateaction作为参数,可以通过action匹配不同的方法改变state,最终返回新的state
  4. dispatch: 接收参数 action,作为执行reducer的参数,并将reducer返回的新的state更改为当前state
  5. subscribe: 用于收集回调函数,在currentState改变时触发。订阅state的变化,当state变化的时候执行回调,可以有多个subscribe,里面的回调会依次执行

createStore:

function createStore(reducer) {
  let state;          // state记录所有状态 
  let listeners = []; // 保存所有注册的回调
  //getState:返回当前的 state
  function getState() { 
    return state 
  }
  //dispatch:根据 action 的 type触发 reducer对应的方法
  function dispatch(action) { 
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  }
  //subscribe:
  function subscribe(fn) {
    listeners.push(fn);
    return function unsubscribe() {
      listeners = listeners.filter(l => l !== fn);
    }
  }
  // store包装一下前面的方法直接返回
  const store =  {
    getState,
    dispatch,
    subscribe
  }
  return store;
}
复制代码

结合上面的例子验证一下效果:

输出一致

分类:
前端
标签: