关于前端:不数不知道React已经有22个hook了

大家好,我卡颂。

5月30日刚好是React10周年纪念日。

我棘手拉了下React最新代码,这一看不要紧,竟然曾经有22个hook了。

其中:

  • react包导出了21个
  • react-dom包导出了1个(useFormStatus

本文会从React这些年倒退脉络的角度,聊聊这些hook的作用。

欢送退出人类高质量前端交换群,带飞

时代的更迭

截止以后,React的倒退次要经验了3个期间:

  • CSR期间(客户端渲染期间)
  • 并发期间
  • RSC期间(服务端组件期间)

以后的22个hook也都是这3个期间的产物。

CSR期间

工夫回到2013年,为了解决facebook日益简单的交互,jordwalke开发了React。通过一段时间摸索,React逐步造成一套满足CSR的开发模式。

这套开发模式从ClassComponent迁徙到FunctionComponent后,便造成了最后的一批hook。这些hook都与CSR的开发模式相干。比方:

与状态的流转相干的:

  1. useState
  2. useReducer
  3. useContext

与解决副作用相干的:

  1. useEffect
  2. useLayoutEffect

与进步操作自由度相干的:

  1. useRef

与性能优化相干的:

  1. useMemo
  2. useCallback

与调试相干:

  1. useDebugValue

随着React继续迭代,又引入了几个hook,实质来说他们都是为了欠缺CSR的开发模式,对现有hook能力进行补充或束缚:

  1. useImperativeHandle(管制useRef避免其失控)
  2. useEffectEvent(对useEffect能力的补充)
  3. useInsertionEffect(对useEffect场景的补充)
  4. useMemoCache(缩小性能优化心智累赘)

这里简略聊聊useMemoCache。长久以来,不论是ClassComponentshouldComponentUpdate,还是FC中2个性能优化相干hook,都存在比拟重的心智累赘,比方:

  • 开发者须要思考是否须要性能优化
  • 开发者须要思考何时应用useMemouseCallback

为了解决这个问题,在2021年的React Conf,黄玄带来了可能通过编译器生成等效于useMemo、useCallback代码的计划 —— React Forget

useMemoCache就是React外部为React Forget提供缓存反对的hook

所以这个hook是给编译器用的,而不是咱们一般开发者。

并发期间

在13年诞生之初,React的作者jordwalke就指出 —— React将来会倒退并发个性

这并不是什么高瞻远瞩的预言,React自身是个重运行时的框架,这意味着他的迭代方向须要围绕运行时开展。而并发个性是一种优良的运行时性能优化策略。

随着并发个性落地,首先推出的是2个并发相干hook

  1. useTransition
  2. useDeferredValue

这2个hook的实质都是升高更新的优先级,更新意味着视图渲染,所以当更新领有不同优先级后,这意味着视图渲染领有不同优先级。

这就是并发更新的实践根底。

然而,并发更新的呈现,突破了React因循多年的一次更新对应一次渲染的模式。

为了让现有的库兼容并发模式,推出了如下hook

  1. useMutableSource
  2. useSyncExternalStore

所以,上述2个hook次要是面向开源库作者。

RSC期间

RSC(服务端组件)是一个盛大的工程,他的实现不是欲速不达的,这一点从新出的hook就能看出。

既然是服务端组件,那就波及到组件在服务端渲染。那么,对于存在惟一标识(比方上面的id props)的组件,如何保障这个惟一标识在服务端与客户端统一呢?

<SomeCpn id={id}/>

如果组件仅在一端渲染,简略应用Math.random()就能取得惟一标识:

const id = Math.random();

<SomeCpn id={id}/>

但如果这段逻辑在服务端/客户端都运行一次,显然id就不惟一了。

为了生成在服务端/客户端惟一的id,有了:

  1. useId

在并发期间,因为引入了渲染优先级的概念,那势必存在一些因为优先级有余,而处于pending中的渲染。

如何展现渲染的pending状态呢?React引入了<Suspense>组件。

到了RSC期间,React团队发现,渲染的pending状态pending数据申请的pending状态不也是pending吗?

换言之,任何须要两头pending状态的流程,不都能够纳入<Suspense>的治理范畴?

那该怎么标记一个流程能够被纳入<Suspense>的治理呢?于是有了:

  1. use

通过这个hook申明的流程中的pending状态都会被纳入<Suspense>的治理。

既然<Suspense>越来越重要,那咱们是不是要针对他做些优化?既然<Suspense>能够在不同视图之间切换,那为他减少缓存显然是种不错的优化形式,于是有了:

  1. useCacheRefresh(用于建设<Suspense>缓存)

到这一步,RSC的基础设施算是搭好了,下一步该构建下层利用了。

在浏览器端,与RSC理念最符合的便是form标签,围绕form标签的action属性,React推出了如下hook

  1. useOptimistic
  2. useFormStatus

这2个hook都是为了优化表单提交这一场景(也能够说是RSC与客户端的交互场景)。

对于这2个hook,更具体的解释能够参考form 元素是 React 的将来一文

总结

如果说CSR期间的hook都是面向开发者间接应用的。那么并发期间最后的2个hookuseTransitionuseDeferredValue)曾经鲜有开发者应用了,而前期相似useMutableSource这样的hook,一般开发者则基本用不到。

同样的,再往后的RSC期间的所有hook,一般开发者都用不到。他们都是为其余库、框架(比方Next.js)提供的。

这标记着React倒退方向的一直变动:

  • 晚期,定位是前端框架,次要为了解决facebook本身问题,顺便开源,受众是开发者
  • 中期,定位是底层UI库,受众是开源库作者
  • 以后,定位是web底层操作系统,受众是下层全栈框架

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理