connect函数原理:
我们将通过自己实现一下connect函数,来学习一下connect函数的底层实现逻辑。
step1
首先通过观察三方库react-redux提供的connect函数,调用时传递了两个参数,返回值又是一个高阶组件,调用该高阶组件将我们自己的组件传递进去。
那么我们先创建一个这样函数,
在src中创建一个hoc文件夹,在hoc中创建一个connect.js
文件
该文件中定义一个 connect 函数,接收两个参数。
返回值是一个高阶组件(即:函数)第12行 。
据高阶组件的定义:对传入的组件做拦截处理加工,要求入参是个组件,返回值也是一个组件。 所以13行定义了一个新组件NewComponent, 在这个新组件对传入的WrapperComponent进行拦截渲染操作。
在思考一下react-redux库提供的connect函数作用是什么?
正如他的字面意思建立连接,就是将store中的存储的值 通过 props的形式传递给组件,从而将组件和store产生关联。
所以我们17行代码渲染WrapperComponent时要将store中的值传递给组件。 我们通过调用外面传入的mapStateToProps(store.getState())
和 mapDispatchToProps(store.dispatch)
获取到Store中要共享出去的值
和 能操作dispatch的自定义方法
。 将这两者通过props传递给WrapperComponent组件。还要注意的是
:第9行的函数执行完,返回的是第12行定义的这个高级组件(函数),该高阶组件调用时return的是NewComponent这个组件
,所以外界真实拿到的是一个内部帮忙渲染了WrapperComponent组件的NewComponent组件,看似开发中在使用WrapperComponent组件,然后给WrapperComponent组件传递props。 其实实际是在使用NewComponent组件,给NewComponent组件传递props。 WrapperComponent组件中并不能拿到外界传递进来的props,所以需要将this.props传递给WrapperComponent组件。 所以17行传递了 this.props
、stateObj
、dispatchObj
。
step2
上面基本完成了connect的实现,但是此时的connect还不能做到当store中的数据改变时,自动刷新组件,需要自己去监听store中数据的变化。通过store.subscribe去订阅,当store中发生修改数据的行为时(不管改的值是不是和上次的值一样,都会触发订阅回调函数)
step3
step2中数据变化时,直接全部强制render性能不好,我们应该只当 修改的值与上次不一样时,才进行render,如果修改的值与上次的一样时,不进行render。
第15行: 用store中共享出来的值,给当前组件state赋值
第25行:通过setState函数,修改组件的State值。 这样就不会当修改的值和上次的值一样时,也去render组件了,因为该组件 继承自 PureComponent , 是做了这个优化的。