「 React 」系列,手动实现一个 redux 与 react-redux

简介: 云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 一、实现一个简易的 Redux 由于公司项目的技术栈是 React,与之配套的公共状态管理的库是 Redux,最近也研究了其中的原理。

云栖号资讯:【点击查看更多行业资讯
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!


一、实现一个简易的 Redux

由于公司项目的技术栈是 React,与之配套的公共状态管理的库是 Redux,最近也研究了其中的原理。由于我之前是硬背 Redux 的用法,时间搁久了总是忘记如何使用。每次要用的时候,就去翻文档,不仅效率低下,用起来也感觉到恶心自己了。搞清楚了背后的机制,写起来就很顺手。相信大家弄懂的基本的实现细节,用起来也会得心应手。

首先思考 Redux 解决了什么问题,为什么要使用它。每当有一些数据要在很多组件中使用的时候,而这些组件跨层级时,props 就不再适合。就需要把这些数据提取出来放在一个模块,我们把它称为公共状态,每当数据改变时,每当数据改变时,它会通知订阅它的说有组件。
要想实现这样的共享的数据,首先想到的必是建一个全局模块,里面存放很多公共的数据。就像这样

1

当状态需要改变的时候,直接显示的赋值,当然,这里要通过观察者模式数据已经改变。不过这样肯定不好

容易误操作,试想我一不小心清空了对象,会影响其他组件都受到污染,肯定要有条件的改变公共状态不易排查错误

1、 实现 getState

既然是共享数据,外部又不能直接改变它,当然就是一个闭包啦。没错,Redux 内部这样的一个机制,通过 store 的一些方法,我们可以搭出大致的骨架

2

毫无疑问,每次调用 getState 就可以拿到最新的 currentState 的值

2、实现 dispatch

在 Redux 里,每当要改变数据,都是调用 dispatch 一个 action,根据 actionType 的值来返回不同的 state,好了,我们就可以这样写

3
4

这样就实现了一个 dispatch,但这样写不好,我们把 switch 这样的逻辑可以提取成一个函数,这也是所说的 reducer,那么,代码就成了这样

5
6

在我们创建 store 的时候,会初始化一次 state,也就是内部会 dispatch 一次,因而

7

到此,即完成了获取和改变状态的功能,验证一下代码

8

尽管如此,当数据改变了,还是不能通知我视图更新。这里需要监听数据的变化,用到了观察者模式,也有人说是发布订阅模式,这两种模式基本的思想一致,但还是有一些区别的,这里观察者模式更加准确。状态数据相当于被观察者,在 createStore 中,我们要维护一个观察者的队列,当执行 subscribe时,把他们放入队列,dispatch的时候,执行队列里的回调

9
10

如此以来,就完成了数据变化,通知组件改变视图的功能,模拟组件运行代码

11

一个最简单的 redux 的应用已经完成,这里还缺饭了大量的参数类型判断,异常处理,异步action、中间件等等。但基本的原理大致相同

二、实现 react-redux

在 react 的项目中,尽管 redux 能实现我们的需求,但写法太过冗余,和 react 的组件写法也不太契合,于是,就有了 react-redux。简单来说,它提供了两大功能:

  • Provider 组件
  • connect 高阶函数

Provider原理是把 store 绑定在 context 上,至于 context,可以为子孙组件的上下文提供 store 对象

13

connect 是一个高阶函数,接收 mapStateToProps, mapDispatchToProps 为参数,并且它返回一个高阶组件。其中,这两个参数都是函数,mapStateToProps 接收 state 返回一个对象,这搞清楚了,mapDispatchToProps 接收一个 dispatch 返回一个对象,我们再来实现它:

14

知道这里,我们通过高阶函数把一些属性挂载到了高阶组件的 props 上,接下来就可以通过 this.props.xxx 调用。此时,我们被 connect 包裹的新组件的 props 上虽然有了值,但是还不具备自动更新的功能,继续改进 connect

function connect(mapStateToProps, mapDispatchToProps) {
  return function(WrappedComponent) {
    class Connect extends Component{ 
         constructor(props) { 
       super(props) 
       this.state = mapStateToProps(store.getState()) 
       this.mapDispatch = mapDispatchToProps(store.dispacth)
      } 
           ComponentDidMount() { 
      //  如果 store 中的状态改变会执行回调函数,此时新获取的 mappedState 和旧的做对比,如若有变化,就setState
       this.unsub = store.subscribe(() => {
        const mappedState = mapStateToProps(store.getState()); 
       if(shallowEqual(this.state, mappedState)) {
            return;
        }
        this.setState(mappedState);
    });
      }
            
    } 
   return Connect
  }
}

如此,一个基本功能的 react-redux 已经实现。

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-04-15
本文作者:李嘉图_M
本文来自:“掘金”,了解相关信息可以关注“掘金”

相关文章
|
1月前
|
前端开发 JavaScript 测试技术
从零开始搭建react+typescript+antd+redux+less+vw自适应项目
从零开始搭建react+typescript+antd+redux+less+vw自适应项目
45 0
|
1月前
|
开发框架 前端开发 JavaScript
使用React、Redux和Bootstrap构建社交媒体应用
使用React、Redux和Bootstrap构建社交媒体应用
13 0
|
3月前
|
前端开发 JavaScript
React中react-redux的基本使用
React中react-redux的基本使用
|
3月前
|
JavaScript 前端开发
React结合Redux实现Todolist
React结合Redux实现Todolist
17 0
|
6月前
|
监控 JavaScript 中间件
React-Redux-DevTools和React-Redux优化
React-Redux-DevTools和React-Redux优化
40 0
|
6月前
|
存储 前端开发 JavaScript
React的诱惑: React-Redux-三大原则和React-Redux-基本使用、优化、综合运用、其他组件使用
React的诱惑: React-Redux-三大原则和React-Redux-基本使用、优化、综合运用、其他组件使用
22 1
|
6月前
|
前端开发 JavaScript 容器
React的魅力: React-Router-集中式管理和Redux-核心概念
React的魅力: React-Router-集中式管理和Redux-核心概念
43 1
|
7月前
|
JavaScript 前端开发 中间件
React(六) —— redux
React(六) —— redux
|
7月前
|
JavaScript 前端开发 算法
|
7月前
|
Web App开发 JavaScript 前端开发
React | Redux的使用详解(二)
React | Redux的使用详解(二)