React18中的useDeferredValue和useTransition的区别(useDeferredValue VS useTransition)

780 阅读2分钟

前言:在学习react18的过程中,对useDeferredValue和useTransition这两个hook的笔记。 自己一点片面的理解:都是为了concurrency,非阻塞更新界面,只是用法不同。

useDeferredValue

  • useDeferredValue is a React Hook that lets you defer updating a part of the UI.
  • useDeferredValue 是一个用来推迟更新部分UI的react 钩子函数。
  • 用法:const deferredValue = useDeferredValue(initValue)
    • 将一个状态标记为延迟状态
    • 首次渲染时,延迟状态和初始状态相同;在更新时,react首先尝试用旧值重渲染,然后在后台尝试用新值渲染;
    • 传递给hook的参数应该是初始类型或者在渲染之外的对象,如果是在渲染时创建的新对象,会导致不必要的后台重渲染
    • 这个hook集成了,在后台更新时不会看到fallback而是旧值
    • 可以用initValue === defferedValue作为stale状态标记
    • 性能优化

useTransition

  • useTransition is a React Hook that lets you update the state without blocking the UI.
  • useTransition 是一个用来更新UI的同时不会阻塞的react 钩子函数。
  • 用法:const [isPending, startTransition] = useTransition()
  • 将一个状态更新标记为非阻塞更新;
  • 函数没有参数;
  • 返回一个包含两个项目的数组-第一个是‘待定’标志,第二个是transition函数;
  • transition函数用来包含一系列set更新函数,且没有返回值;
    startTransition(() => {  
       setTab(nextTab);  
       }); 
    
  • useTransition 用法和其他钩子函数一样,在组件内部或者自定义钩子函数内部使用,并且不能在条件函数内使用;如果要在其他地方使用可以直接使用 startTransition API
  • 只有当你能调用到需要更新的state的set函数时,才能用这个钩子函数。如果为了响应一个外部传入的prop或者自定义钩子函数值,使用useDeferredValue 函数
  • 被标记为transition的状态更新会被其他状态更新打断。
  • Transition updates can’t be used to control text inputs.
     function handleChange(e) {  
        // ❌ Can't use transitions for controlled input state  
        startTransition(() => {  
        setText(e.target.value);  
        });  
      }
    

因为文本输入应该是同步的,建议改用useDefferValue()或者定义两个状态,一个输入状态,一个用于更新transition

  • 如果同时有多个transitions,react目前会批处理。这个限制可能会在之后解除。
  • transition函数包含的回调应当是同步的,如果有异步需求,将transition放在异步函数内;