前言:在学习react18的过程中,对useDeferredValue和useTransition这两个hook的笔记。 自己一点片面的理解:都是为了concurrency,非阻塞更新界面,只是用法不同。
useDeferredValue
useDeferredValueis 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
useTransitionis 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放在异步函数内;