redux作为大型应用的状态管理工具,如果想配合react使用,需要借助react-redux。
redux主要完成两件事情:
- 负责应用的状态管理,保证单向数据流
- 当应用状态发生变化,触发监听器。
那么,如果想要将react和redux搭配使用,就需要react组件可以根据redux中所存储的状态(store)更新view。
并且可以改变store。其实react-redux主要就是完成了这两件事情。
第一,通过将store传入root组件的context,使子节点可以获取到 state。
第二,通过store.subscribe 订阅store的变化,更新组件。
另外还有对于性能的优化,减少不必要的渲染。
熟悉使用方法
首先我们熟悉一下react-redux的基本使用
1 | import React from 'react'; |
从上面的例子中我们可以看出,react-redux使用非常简单,仅仅使用了两个API,Provider
与 connect
。
- Provider: 接收从redux而来的store,以供子组件使用。
- connect: 高阶组件,当组件需要获取或者想要改变store的时候使用。可以接受四个参数:
- mapStateToProps:取store数据,传递给组件。
- mapDispatchToProps:改变store数据。
- mergeProps:可以在其中对 mapStateToProps, mapDispatchToProps的结果进一步处理
- options:一些配置项,例如 pure.当设置为true时,会避免不必要的渲染
源码解读
Provider
1 | class Provider extends Component { |
够简单吧,仅仅是把store放在了context下。subscriptionKey 可以暂时不用管。
connect
首先我们先回忆一下connect使用方法:
1 | connect(mapStateToProps,mapDispatchToProps,mergeProps,options)(App); |
connect源码:
1 | export function createConnect({ |
这段我们可以知道,connect是对connectHOC(connectAdvanced)的封装,connectAdvanced使用了 defaultSelectorFactory,来创建selector。
react-redux 默认的 selectorFactory 中包含了很多性能优化的部分(我们一会儿会看到)。
其实react-redux 也提供了connectAdvanced API,为了便于大家理解我通过改变开头的例子,了解一下selectorFactory 是如何工作的。
1 | // const AppContainer = connect( |
这是一个简单的 selectorFactory,主要体现了其是如何工作的,让大家有一个大概的了解。
下面来看一下react-redux是如何实现 selectorFactory 的
selectorFactory
在解读代码之前,我想先说一下options.pure的作用。不知道大家还记得吗,在开头的例子有一个配置项pure。作用是减少运算优化性能。当设置为false时,react-redux将不会优化,store.subscirbe事件触发,组件就会渲染,即使是没有用到的state更新,也会这样,举个例子
1 | // 大家都知道reducer的写法 |
举了个不恰当的例子,大家千万不要这么干。。。
源码:
1 | export default function finalPropsSelectorFactory(dispatch, { |
这里很好理解,是对 selectorFactory 的封装,根据 options.pure 的值,选取不同的 SelectorFactory;
- options.pure 为 false 时,使用 impureFinalPropsSelectorFactory
- options.pure 为 true 时,使用 pureFinalPropsSelectorFactory
先来看看简单的 impureFinalPropsSelectorFactory
,其实和之前实现的 selectorFactory,差不多,无脑计算返回新值。
1 | export function impureFinalPropsSelectorFactory( |
怎么样,和之前自己实现的差不多吧,自己实现的还有一个浅对比呢~ 笑哭
pureFinalPropsSelectorFactory
1 | export function pureFinalPropsSelectorFactory( |
一句话: 在需要的时候才执行mapStateToProps,mapDispatchToProps,mergeProps
为了减少篇幅,挑部分讲解。其实这篇已经很长了有没有,不知道看到这里的你,犯困了没有?
还是已经睡着了? 上个图醒醒脑
言归正传,这里也分两种情况:
- 当第一次运行时,执行handleFirstCall,将三个map函数运行一遍,并将结果缓存下来
- 之后运行 handleSubsequentCalls,在其中将新的值和缓存的值做比较,如果变化,将重新求值并返回,如果没变化,返回缓存的旧值。
其中 mapFunction.dependsOnOwnProps 代表你传入的mapStateToProps是否使用了ownProps。
如果没有使用,那么props的变化将不会影响结果,换句话说对应的mapFunction将不会执行。
判断方法也很简单,就是获取function形参长度,如何获得呢? mdn function.length
总结
这边文章主要讲了react-redux使用方法以及分析了源码中 Provider、connect、selectorFactory。中间也穿插了一些demo方便大家理解。
到目前为止大家应该已经熟悉了整个框架的工作流程。由于感觉篇幅过长,所以决定分为两期来讲解。下面一期中主要是剩下的 connectHOC(connectAdvanced),这个才是react-redux的核心。
希望看完的朋友没有浪费你们时间,有所帮助,有什么意见尽管提,就当你们自己是产品(🐶)好le.
写完又读了一遍,感觉篇幅其实不长,想想应该是自己写的累了。。。