用TS简单手写一个redux。

127 阅读1分钟

Redux很多地方都在用,我也用了几年了,今天这篇文章就是自己来实现一个Redux,以便于深入理解他的原理。

image.png

基本概念

Redux的概念有很多文章都讲过,想必大家都看过很多了,我这里不再展开,只是简单提一下。Redux基本概念主要有以下几个:

Store

Store就是一个仓库,它存储了所有的状态(State)。

const pre: {} = {};

Actions

一个Action就是一个动作,这个动作的目的是更改Store中的某个状态,Store还是上面的那个仓库.

type Action = { type: string; payload?: any };

Reducers

操作要靠Reducer,Reducer就是根据接收的Action来改变Store中的状态

const reducer = (pre: {}, action: { type: string; payload?: any }) => {
switch (action.type) {
  default:
    return pre;
}
};

实现

createStore

createStore:这个API接受reducer方法作为参数,返回一个store,主要功能都在这个store上。

subscribe

store.subscribe: 订阅state的变化,当state变化的时候执行回调,可以有多个subscribe,里面的回调会依次执行。

dispatch

store.dispatch: 发出action的方法,每次dispatch action都会执行reducer生成新的state,然后执行subscribe注册的回调。

getState

store.getState:一个简单的方法,返回当前的state

完整代码

本质也就是发布订阅的模式

type CbList = (() => void) | null;
type Action = { type: string; payload?: any };
type Reducer<S> = (preState: S, action: Action) => S;

class MyCreatStore<S> {
  private cbList: CbList[];
  private reducer: Reducer<S>;
  private state: S;
  constructor(reducer: Reducer<S>, initState: S) {
    this.reducer = reducer;
    this.state = initState;
    this.cbList = [];
  }

  dispatch(action: Action) {
    this.state = this.reducer(this.state, action);
    this.cbList.forEach((cb) => cb && cb());
  }

  subscibe(cb: CbList) {
    this.cbList.push(cb);
    let index = this.cbList.length - 1;
    return () => {
      this.cbList[index] = null;
    };
  }

  getState() {
    return this.state;
  }
}