欢迎光临散文网 会员登陆 & 注册

React 18的新hook,useSyncExternalStore分析

2023-05-11 16:59 作者:小老虎Tigger  | 我要投稿

在react18之后,很多状态管理库,都使用了useSyncExternalStore这个库去适应react18的concurrent features,虽然concurrent在之前的版本中就已经提供,但是默认并不开启。

在说明useSyncExternalStore之前,我们先来看一下redux相关的一些信息。

redux是一个状态管理工具,它可以运行在react、vue等库中,在react中使用,通常需要使用react-redux让redux和react连接起来,而现在流行的redux-toolkit则是一个让我们更加方便的可以创建store、action、reducer的一个工具。

redux的设计理念其实一直没有变化,但是随着react的不断更新,react-redux就需要不断的做出调整。

那么react-redux都有哪些改变呢?

最初react-redux其实相当简单,我们使用它提供的connect函数将redux和react连接起来,其实connect其实就是一个高阶组件,因为hooks没有流行起来之前,class组件是主流,所以这种装饰器写法相当简洁。我们暂且将传入connect的组件称为子组件,将connect创建的组件成为称为父组件。

connect的第一个参数名称mapStateToProps,其实就是这个函数的作用,根据传入的对象在父组件中创建对应的state,对store进行订阅,然后再将state通过props传递到传入的子组件中使用。那么这个时候调用dispatch更改store数据之后,就会触发订阅,调用setState,相应的子组件也会更新。

后来,hooks出现之后,函数式组件成为主流,class组件基本销声匿迹。react-redux顺应潮流,接着提供了useSelector、useDispatch等hook,以便我们在函数式组件中使用。

useSelector其实也比较简单,它根据传入的selector返回store中的值,同时也会去订阅store,等到store数据变化,则调用forceRender触发更新。

这种发布订阅以及触发更新的模式,和antd中form基本一样。

而到了react18中,我们再看react-redux中useSelector的实现,我们如果把其中代码精简一下,则变成了下面这样

所有的内在逻辑其实都放到了useSyncExternalStore中,当成一个react的api提供给其他状态管理库的开发者使用。我们如果把useSyncExternalStore的实现代码删减一下,就能发现和上面react-redux里面的代码逻辑非常像,也是订阅、然后再store变化时forceUpdate,其实都是通过useState触发更新。

很多文章里面都讲useSyncExternalStore是为了解决react18中concurrent特性引发的UI撕裂问题,但是本质上,这个hook其实就是对使用外部数据时的逻辑内聚,我们只需要在使用时提供给react一个读取store的方法getSnapshot,一个用于订阅的方法subscribe,我们就可以在store的更新后自己去控制触发react更新。react在调用我们提供给它的subscribe函数时,传入的callback,其实就是一个forceUpdate。

上面的例子,本质上和下面是一样的


React 18的新hook,useSyncExternalStore分析的评论 (共 条)

分享到微博请遵守国家法律