阅读 59

手写简易版react-redux connect函数

为了简化store状态变化的订阅,在平时使用redux的时候通常搭配react-redux来使用。在export页面前需要使用react-redux提供的connect方法来连接store,映射state和action到组件的props中。connect方法返回一个函数,该函数接收一个组件作为其参数,其执行结果返回一个新的组件。其中的原理就是利用了react的高阶组件,对HOC不熟悉的需要看一下官方的文档。

下面让我们直接来写一个简易版的connect来了解下connect原理。

先使用create-react-app 新建一个react应用,yarn安装redux、react-redux。

初始化 一个简单的store。

1.png

接下来不使用connect函数,使用redux提供的方法来绑定数据至组件。 2.png

可以看到状态的订阅很繁琐,而且相同的逻辑在其他组件中也会复写。接下来我们自己创建一个connect函数,在 src目录下新建一个utils文件夹,在utils中创建connect.js文件。 3.png

我们先回顾下官方react-redux的connect使用方法:connect(mapStateToProps,mapDispachToProp)(component) 。根据使用方式可以判断调用connect函数后返回了一个新的函数,并且接收一个组件作为参数。那么我们就要在刚创建的connect函数中增加返回函数。 4.png

该函数调用后返回一个新的具有原组件的属性方法,同时也要具有store中的state和action。这时候就要创建一个新组件,并且渲染作为参数传递的wrappedComponent组件。 5.png

接下来还要把接收的mapStateToProps,mapDispachToProp给整到WrappedComponent中,回顾一下mapStateToProp,mapDispachToProp的用法:

const mapStateToProp = state => ({...}) const mapDispachToProp = dispatch => ({...})

也就是说我们要调用这两个方法,并传递state,dispatch作为参数,其返回值要作为prop传递给WrappedComponent。 6.png

这样写是不是就可以了呢。当我们调用connect处理完组件导出后,在其他使用到该组件的地方可能会给组件传递不同的props,直接这样写的话,传递的props则无法到达WrappedComponent,这里还需要将props解构传递给WrappedComponent。 7.png

直接在组件中使用看看效果,定义mapStateToProps,mapDispachToProp,同时也给App组件props加个text。<App text="hello" />

8.png

似乎是成功了,这样子我们就可以把组件多余的代码删掉了,一下子就简洁了很多。 9.png

新增了两个按钮点击触发action更新状态,然而在页面中点击似乎并没有什么卵用,页面无任何变化,原因很简单就是没有订阅store的更新,组件的props一直未改变,这就要在connect中处理一下,原来的写法就要改变一下。 10.png

再测试一下就没有啥问题了,但是现在这个函数只能在自己的项目中使用,因为这个函数依赖了项目中的store,在别的项目中使用就需要修改store的路径。react-redux可不会让用户修改它的源代码,react-redux使用了react的context来为connect函数提供store。新建context.js 文件,创建context,然后在connect中导入,connect中的store都要换成context。 11.png

在应用的入口出添加Provider,这样在任何地方使用connect 都可以拿到store的值了,这样一个简单版的connect函数就完成了。 12.png

13.png

这个简单版的connect函数只是帮助我们大致了解一下connect函数为我们做了哪些事情,了解其怎么工作的之后,我们在使用的时候才会更加得心应手。react-redux官方库的实现与之复杂得多,但主要流程都类似并且大部分都使用了hook来实现,,connect方法只是connectAdvanced的表象,connect将接收到的args变成一个兼容的selectorFactory,将其做为参数传递给connectAdvanced,connectAdvanced再将其传递给wrapedComponent,每次wrapedComponent被实例化或者热重载时,selectorFactory都会更新一个新的props selector,当wrapedComponet接收到新的store中的状态,props selector就会被调用生成props。

文章分类
前端
文章标签