React-Redux 源码阅读笔记 #77
zhangyu1818
announced in
zh-cn
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
自从我学习过高阶组件,大家流传的就是
connect()
就是一个高阶组件,所以在我长久的认知中,认为connect()
仅仅是一个从context
中筛选出state
,传入给子组件的简单高阶组件我个人用
redux
是比较少的,自从hooks
出了以后,就经常用useContext
+useReducer
来实现简单的redux
的功能,所以也认为在react-redux
里,connect()
会像useReducer
一样,数据重新渲染由React
控制结论当然不是这样,并且
connect()
组件也不简单,可以说在我打开源码的第一时间傻眼了,下面就来好好的分析下react-redux
原理简述
在分析源码之前,需要先将
react-redux
的原理简述一下,否则光干看代码还是会比较懵先简单的画一个流程
react-redux
的核心机制是通知订阅模式,源码中有一个Subscription
类,它的作用主要是订阅父级的更新和通知子级的更新,也就是它既可以订阅别人,别人也可以订阅它,同时可以通知订阅它的Subscription
最外层的
Provider
组件的Context
里包含了的store
(也就是我们传入的)和生成的Subscription
实例,它的Subscription
实例订阅的则是redux
的subscrib()
当我们使用了
connect()
时,它会生成一个新组件<Component1/>
,<Component1/>
里会生成一个Subscription
实例,它会订阅父级(这时是Provider
)的Subscription
实例,同时将自己的Subscription
覆盖进Context
,再包装我们传入的组件,如下模式如果在
<Component1/>
里的子组件又有connect()
,那么生成的<Component2/>
组件的Subscription
实例会订阅父级<Component1/>
的Subscription
实例,同时再将自己的Subscription
覆盖进Context
在组件挂载完成后,如果
store
有更新,Provider
会通知下一级组件的Subscription
,下一级组件又回通知自己的下一级组件在订阅的时候,会将更新自己组件的方法通过回调
onStateChange()
传入父级的Subscription
一旦父级接收到通知,就会循环调用订阅自己的组件的
onStateChange
来更新它们更新的原理就是使用我们传入的
mapStateToProps
和mapDispatchToProps
,结合内置的selectorFactor()
来对比state
和props
,一旦有改变就强制更新自己,所以我们传入的WrappedComponent
也被强制更新了原理简单来讲就是这样,下面来看源码
源码简析
在顺着流程分析之前,先看看贯通整个
react-redux
更新流程的Subscription
类Subscription
省略了一些代码,
Subscription
类主要就是创建一个既有监听功能又有订阅功能的对象接下来就顺着流程来逐步分析,首先先看
Provider
里实现了什么Provider
Provider
是一个比较简单的组件,主要做了2件事redux
的subscribe()
事件Subscription
实例传入Context
方便子级订阅接下来看看核心
connect
组件connect
connect()
其实是由createConnect()
默认创建出来的,虽然我们也可以调用createConnect()
创建自定义的connect()
,但是基本用不上可以看到我们传入的
mapStateToProps
,mapDispatchToProps
、mergeProps
实际上是通过了一个match()
函数的包装校验这里就以
mapStateToPropsFactories
也就是defaultMapStateToPropsFactories
为例mapStateToPropsFactories
在
match
校验的时候,首先会判断我们是否传入的mapStateToProps
,没有传入则调用wrapMapToPropsConstant
创建一个默认方法如果传入则会调用
wrapMapToPropsFunc
对我们的方法做一层包装,主要判断我们的方法是否需要依赖props
wrapMapToProps
这里的判断实际都是为了给后面的
selectorFactory
铺路,它的作用是根据state
或props
的变化,判断是否需要调用我们的mapStateToProps
、mapDispatchToProps
和mergeProps
返回新的数据下面看看
selectorFactory
的实现selectorFactory
现在的流程,知道了调用
connect()
后,会对我们的传入的函数进行一层包装来判断是否依赖于props
,随后selectorFactory
调用时会根据结果有无变化来判断是否需要重新调用我们的函数现在就来看核心的高阶函数的实现
connectAdvanced
connectAdvanced
看完整体
connectAdvanced
后,还是有1个问题没想明白store
的subscribe
?因为在
useSelector
的hooks
方法里,根本没法传递context
,订阅的不都是Provider
吗?不就没有了connect()
的订阅层级了希望有大佬能解答这个小小的疑惑
整个
react-redux
的源码绕来绕去,真的挺复杂的,从第一天一脸懵逼到第七天基本搞明白,甚至自己可以写一个简易版,还是很高兴的Beta Was this translation helpful? Give feedback.
All reactions