React 18 在今年稍早推出了稳定版,听说解决了很多长久以来的问题,所以花了点时间,体验看看这些新功能,并且统整一下,写成今天的文章
5 new Hooks
useTransitionuseDeferredValueuseIduseSyncExternalStoreuseInsertionEffectuseTransition
React 18 新加的功能之一,就是 Transition
, 作用在于将State分为 紧急(Urgent)
及 非紧急(Non-urgent)
两种,Transition 对应的也就是 非紧急的state
更新。
const [isPending, startTransition] = useTransition();startTransition(()=>{ // 显示Todo 内容的状态更新不是紧急至必须马上有反应。 setTodos(todos);})// isPending用来表示该Transition 是否已经完结。
如果不需要 isPending ,可以改写成:
import { startTransition } from 'react';
useDeferredValue
useDeferredValue 主要是解决一直重複 render 的行为,大家都知道 React 是资料驱动画面,所以当如果取得资料上面有延迟,那麽画面上就会有卡顿的感觉
传统上会用 debounce 来解决这类的问题,但是跟 debouce 不一样的是 useDeferredValue 是 被触发后
才做回传更新后的资料,引发 re-render,而 debounce 是 不管有没有需要
,都会固定去触发
p.s. 依赖 deferred value 的 child component 要记得使用 useMemo,避免不必要的 re-render
const deferredValue = useDeferredValue(value);// 参数是设定要延迟的 value 值// 最后返回一个延迟的值 deferredValue
useTransition vs useDeferredValue
以下是我个人对于使用上的感觉,或许不是绝对
体验下来感觉这两个使用起来差不多,都是将事件状态改成 Non-urgent
,不过可监听的对象数量不一样,useTransition 可针对多个状态一次改成 Non-urgent,useDeferredValue 感觉是针对单一状态去改变
useId
useId is a hook for generating unique IDs that are stable across the server and client
Note: useId is not for generating keys in a list. Keys should be generated from your data.
记得别把 useId 是用到 list 中,list 中的 keys 应该是要取自于你的资料
const id = useId();
useSyncExternalStore
https://andyyou.github.io/2022/01/05/use-sync-external-store-with-solving-problem/
https://milkmidi.medium.com/react-18-usesyncexternalstore-a427bf82c198
useInsertionEffect
useInsertionEffect工作原理类似useLayoutEffect,区别在于回调执行时还不能访问ref中的DOM节点。
你可以在这个 Hook 内操作全局 DOM 节点。
function useCSS(rule) { useInsertionEffect(() => { if (!isInserted.has(rule)) { isInserted.add(rule); document.head.appendChild(getStyleForRule(rule)); } }); return rule;}function Component() { let className = useCSS(rule); return <div className={className} />;}
Automatic Batching
17版以前,只有 useState 会做 Automatic Batching,而其他的非同步行为,例如: Promise, setTimeout,fetch 是不会自动 Automatic Batching ,不过 18 版后这些非同步预设都会自动 Automatic Batching
不过也不是所有的部分都需要 Automatic Batching ,可透过 flushSync 来跳脱 Automatic Batching
flushSync(() => { setState(true);});
以上简单介绍了几个 React18 新增的 Hooks 跟 Automatic Batching,如果对于 React 18 有兴趣的朋友可以去官网看看,下面也整理里一些参考的文章,方便大家去学习,那么我们下次见,掰掰~~
文章同步到我的Medium,有兴趣的读者欢迎去看看
参考文章:
https://andyyou.github.io/2022/01/05/use-sync-external-store-with-solving-problem/
https://milkmidi.medium.com/react-18-usesyncexternalstore-a427bf82c198
https://segmentfault.com/a/1190000040966821
https://tecky.io/en/blog/React-18-%E7%99%BB%E5%A0%B4-!-%E6%96%B0%E5%A2%9E%E5%8A%9F%E8%83%BD%E5%A4%A7%E7%B0%A1%E4%BB%8B/
https://beta.reactjs.org/
https://gcdeng.com/blog/react-hooks