仿写 redux 源码(三)

138 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

前情回顾

  • 前面一篇文章,我们介绍了 redux 创建 store 的例子,以及在 react 中使用 redux 的例子
  • 这篇文章我们将深入原理实现 createStore 方法

实现 createStore

  • redux 的代码其实非常简洁,并且代码逻辑非常清晰明了
  • 下面是我的 createStore 的源码仿写
export function createStore(reducer) {
  let currentState; // 用于存放 store 的数据
  let listeners = []; // 用于存放监听的回掉

  const getState = () => currentState;

  const dispatch = (action) => {
    // 执行 reducer
    currentState = reducer(currentState, action);

    // 执行监听的回掉
    listeners.forEach((listener) => listener());
  };

  // 注册监听回掉
  const subscribe = (newListener) => {
    listeners.push(newListener);

    // 返回一个移除监听回掉的方法
    return () => {
      listeners = listeners.filter((listener) => listener !== newListener);
    };
  };

  // 解决 currentState 没有初始值的问题
  dispatch({ type: `${Date.now()}` });

  return {
    getState,
    dispatch,
    subscribe,
  };
}
  • createStore 其实就是一个函数

    • 它接收一个,定义了 store 中数据更新规则的 reducer 函数
    • 然后返回一个对象,其中包括getStatedispatchsubscribe等与 store 进行交互的方法 API
  • currentState 就是当前的状态数据

  • getState 是用来获取 store 数据的方法,实现起来很简单,直接返回 currentState 即可

  • dispatch 是用来提交数据更新到 store 的方法,其接受一个 action 纯对象

    • action 对象包含了数据更新的类型 type,以及数据更新的参数 payload
    • 执行 reducer 函数,并将当前的 state 与 action 作为参数传入,即可完成 store 数据的更新
    • reducer 执行完成之后,生产一个新的状态,然后赋值给 currentState
    • 更新数据之后,需要驱动视图更新
  • 那么在数据更新之后,如何让视图进行更新呢?

    • 视图如何更新只有视图知道
      • 所以可以将视图的更新函数作为回掉函数注册到 store 中
      • 当数据更新时,调用视图更新的回掉函数即可完成视图的更新
    • redux 的解决方案就是
      • 在 store 中定义一个存放监听函数的数组 listeners
      • 提供一个 subscribe 函数用于注册视图更新的回掉函数
        • 该 subscribe 函数接收一个监听回掉
        • 返回一个注销该监听回掉的函数
      • 只要页面通过 dispatch 提交数据更新,就可以遍历 listeners,并执行每一个监听函数

小结

  • 本文实现了 redux 中 createStore 方法的功能,下篇文章我们将实现 combineReducers

  • 今天的分享就到这里了,欢迎大家在评论区里面进行讨论 👏

  • 如果觉得文章写的不错的话,希望大家不要吝惜点赞,大家的鼓励是我分享的最大动力 🥰