React@16.x(56)Redux@4.x(5)- 实现 createStore

1,分析

createStore(),参数1为 reducer,参数2为初始化的 state(中间件参数,之后的文章会介绍)。返回的 store 对象有以下属性:

  • dispatch 方法,用于分发 action
  • getState 方法,用于得到最新的 state
  • subscribe 方法,用于在 state 发生变化时执行。

2,实现

2.1,基础实现

export const createStore = (reducer, defaultState) => {
    let currentReducer = reducer;
    let currentState = defaultState;
    let listeners = [];

    const dispatch = (action) => {
        currentState = currentReducer(currentState, action);
        // 每次更新时,遍历监听器。
        for (const listener of listeners) {
            listener();
        }
    };

    const getState = () => {
        return currentState;
    };

    const subscribe = (listener) => {
        listeners.push(listener);
        // 取消监听
        return () => {
            listeners = listeners.filter((f) => f !== listener);
        };
    };

    // createStore 创建时会调用一次。
    dispatch({
        type: "@@redux/INITg.p.0.c.e.f",
    });

    return {
        dispatch,
        getState,
        subscribe,
    };
};

2.2,优化

2.2.1,随机字符串

createStore 创建时调用 dispatch() 传入的 type 是随机 36位 字符串。可以这样生成:

Math.random().toString(36) // '0.ge0p9nwtid7'
Math.random().toString(36).substring(2, 8) // 'ge0p9n'
Math.random().toString(36).substring(2, 8).split('').join('.') // 'g.e.0.p.9.n'
export const createStore = (reducer, defaultState) => {
    // ...
    dispatch({
        type: `@@redux/INIT${getRandomString()}`,
    });
	// ...
};

function getRandomString() {
    return Math.random().toString(36).substring(2, 8).split('').join('.')
}

2.2.2,action 的判断

action 有一些限制

  • 必须是一个平面对象。
  • 必须有 type 属性。
const dispatch = (action) => {
    if (typeof action !== "object" || Object.getPrototypeOf(action) !== Object.prototype) {
        throw new Error("action 必须是一个 plain Object");
    }
    if (action.type === undefined) {
        throw new Error("action 必须有 type 属性");
    }
   // ...
};

2.2.2,监听器的优化

监听器返回的函数执行一次之后,再次执行时应该立即返回且什么都不做。因为对应的监听器已经卸载了。

const subscribe = (listener) => {
    listeners.push(listener);
    let isRemove = false;
    return () => {
        if (isRemove) {
            return;
        } else {
            isRemove = true;
            listeners = listeners.filter((f) => f !== listener);
        }
    };
};

2.3,最终形态

export const createStore = (reducer, defaultState) => {
    let currentReducer = reducer;
    let currentState = defaultState;
    let listeners = [];

    const dispatch = (action) => {
        if (typeof action !== "object" || Object.getPrototypeOf(action) !== Object.prototype) {
            throw new Error("action 必须是一个 plain Object");
        }
        if (action.type === undefined) {
            throw new Error("action 必须有 type 属性");
        }
        currentState = currentReducer(currentState, action);
        // 每次更新时,遍历监听器。
        for (const listener of listeners) {
            listener();
        }
    };

    const getState = () => {
        return currentState;
    };

    const subscribe = (listener) => {
        listeners.push(listener);
        let isRemove = false;
        // 取消监听
        return () => {
            if (isRemove) {
                return;
            } else {
                isRemove = true;
                listeners = listeners.filter((f) => f !== listener);
            }
        };
    };

    // createStore 创建时会调用一次。
    dispatch({
        type: `@@redux/INIT${getRandomString}`,
    });

    return {
        dispatch,
        getState,
        subscribe,
    };
};

function getRandomString() {
    return Math.random().toString(36).substring(2, 8).split("").join(".");
}

以上。

相关推荐

  1. React@16.x56Redux@4.x5)- 实现 createStore

    2024-07-12 23:56:02       17 阅读
  2. React@16.x54Redux@4.x(3)- reducer

    2024-07-12 23:56:02       23 阅读
  3. React@16.x58Redux@4.x(7)- 实现 combineReducers

    2024-07-12 23:56:02       20 阅读
  4. React@16.x57Redux@4.x(6)- 实现 bindActionCreators

    2024-07-12 23:56:02       25 阅读
  5. React@16.x55Redux@4.x4)- store

    2024-07-12 23:56:02       22 阅读
  6. React@16.x53Redux@4.x(2)- action

    2024-07-12 23:56:02       21 阅读
  7. React@16.x52Redux@4.x(1)- 核心概念

    2024-07-12 23:56:02       20 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 23:56:02       53 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 23:56:02       56 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 23:56:02       46 阅读
  4. Python语言-面向对象

    2024-07-12 23:56:02       57 阅读

热门阅读

  1. leetcode热题100.零钱兑换(动态规划)

    2024-07-12 23:56:02       16 阅读
  2. 跟我从零开始学STL(STL代码基础02)---vector容器

    2024-07-12 23:56:02       17 阅读
  3. 数据结构第18节 散列表 - 应用

    2024-07-12 23:56:02       19 阅读
  4. C# Modbus

    2024-07-12 23:56:02       19 阅读
  5. 安卓热门面试题一

    2024-07-12 23:56:02       17 阅读
  6. React组件间通信的几种方式

    2024-07-12 23:56:02       17 阅读
  7. TCP/IP模型和OSI模型的区别(面试题)

    2024-07-12 23:56:02       18 阅读
  8. opencv--把cv::Mat数据转为二进制数据的保存和读取

    2024-07-12 23:56:02       18 阅读
  9. 扫地机器人如何进行MTBF测试

    2024-07-12 23:56:02       16 阅读