Open jtwang7 opened 1 year ago
转载文章:
🤓 仅供学习使用,后续会添加个人理解
在Web应用中,UI更新(比如在输入框中输入字段,从下拉框选择一个值)的优先级应该高一些,而其他操作(比如显示列表过滤内容)优先级要低一些。从React 18(2021.06发布了alpha版本)开始,我们就可以开启并发模式-concurrent,concurrent模式允许将UI更新标记为高优先级的或者可中断的低优先级操作。在这篇文章中,你会掌握如何使用useTransition()将UI更新标记为低优先级,这种操作对大量的非紧急更新非常有用。
默认情况下,我们认为React中的所有更新都是紧急的(也就是所有更新的优先级相同)。那会导致一个问题-快速更新会被大量更新拖慢速度。然而,从React 18中新增特性-concurrency之后,你就可以将某些更新标记为可中断的和非紧急的-也就是所谓的transitions。这种新特性在大量的UI更新操作中尤其有效,比如过滤一个较大的列表。 ❇️ useTransition 这个钩子函数使得用户能够在React组件中使用concurrent模式特性: 调用 const [isPending, startTransition] = useTransitionHook() 返回一个具有两个成员的数组:
const [isPending, startTransition] = useTransitionHook()
import { useTransition } from 'react'; function MyComponent() { const [isPending, startTransition] = useTransition(); // ... const someEventHandler = (event) => { startTransition(() => { // Mark updates as transitions setValue(event.target.value); }); } return <HeavyComponent value={value} />; }
接下来考虑一个所有更新都很紧急的例子,以及这些大量更新是如何影响用户体验的。 比如有一个员工名字列表和一个查找员工的姓名搜索框,这个组件会高亮显示匹配搜索内容的员工姓名。 以下是可能实现的代码:
import { useState } from 'react'; export function FilterList({ names }) { const [query, setQuery] = useState(''); const changeHandler = ({ target: { value } }) => setQuery(value); return ( <div> <input onChange={changeHandler} value={query} type="text" /> {names.map((name, i) => ( <ListItem key={i} name={name} highlight={query} /> ))} </div> ); } function ListItem({ name, highlight }) { const index = name.toLowerCase().indexOf(highlight.toLowerCase()); if (index === -1) { return <div>{name}</div>; } return ( <div> {name.slice(0, index)} <span className="highlight"> {name.slice(index, index + highlight.length)} </span> {name.slice(index + highlight.length)} </div> ); }
在组件内部,query是包含查询字符串的状态变量。输入框是一个控制组件-用于在用户输入改变时更新query状态变量。当使用者在快速在输入框内键入查询字段,你可能会注意到键入延迟以及用户界面在明显的时间内没有响应。 👉 为什么会出现这种现象,如何解决呢? 在用户键入时更新输入框的值是一个必须快速执行的紧急任务,更新高亮显示匹配列表是一个繁重且不紧急的任务。大量的非紧急任务落后于轻量的紧急任务。useTransition()钩子能够帮助你区分紧急的UI更新和非紧急的UI更新。
之前已经提高了,你可以使用 useTransition 告诉React哪些UI更新是紧急的(比如更新输入框的值)和哪些UI更新是不紧急的transitions(比如更新高亮匹配查询内容的姓名列表) 💡 我们来对FilterList组件做一下必要的调整: 首先,我们调用 [isPending, startTransition] = useTransition() 钩子来访问startTransition()函数,然后专门这个transition创建了一个保存状态的状态变量。
[isPending, startTransition] = useTransition()
import React, { useState, useTransition } from "react"; export function FilterList({ names }) { const [query, setQuery] = useState(""); const [highlight, setHighlight] = useState(""); const [isPending, startTransition] = useTransition(); const changeHandler = ({ target: { value } }) => { setQuery(value); startTransition(() => setHighlight(value)); }; return ( <div> <input onChange={changeHandler} value={query} type="text" /> {isPending ? 'pending' : ( names.map((name, i) => ( <ListItem key={i} name={name} highlight={highlight} /> )) )} </div> ); } function ListItem({ name, highlight }) { const index = name.toLowerCase().indexOf(highlight.toLowerCase()); if (index === -1) { return <div>{name}</div>; } return ( <div> {name.slice(0, index)} <span className="highlight"> {name.slice(index, index + highlight.length)} </span> {name.slice(index + highlight.length)} </div> ); }
使用了transitionos特性,如果你非常快速地在输入框中键入,你会注意到高亮列表的延迟更新。 React将紧急任务(当用户键入时更新输入框)的更新和非紧急任务(高亮显示过滤内容)的渲染区分开了,这样的操作提升了用户体验。
React中的并发模式(concurrent mode)将紧急任务和非紧急任务区分开,使UI更新更加人性化。在开启React 18并发模式新特性之后,你可以使用useTransition()钩子进而使用startTransition(callback)函数。 useTransition()使你能够将默写更新标记为过渡(transitions):
const [isPending, startTransition] = useTransition(); startTransition(() => { // Mark updates as transitions setStateValue(newValue); });
React - useTransition
转载文章:
在Web应用中,UI更新(比如在输入框中输入字段,从下拉框选择一个值)的优先级应该高一些,而其他操作(比如显示列表过滤内容)优先级要低一些。从React 18(2021.06发布了alpha版本)开始,我们就可以开启并发模式-concurrent,concurrent模式允许将UI更新标记为高优先级的或者可中断的低优先级操作。在这篇文章中,你会掌握如何使用useTransition()将UI更新标记为低优先级,这种操作对大量的非紧急更新非常有用。
useTransition 钩子
默认情况下,我们认为React中的所有更新都是紧急的(也就是所有更新的优先级相同)。那会导致一个问题-快速更新会被大量更新拖慢速度。然而,从React 18中新增特性-concurrency之后,你就可以将某些更新标记为可中断的和非紧急的-也就是所谓的transitions。这种新特性在大量的UI更新操作中尤其有效,比如过滤一个较大的列表。 ❇️ useTransition 这个钩子函数使得用户能够在React组件中使用concurrent模式特性: 调用
const [isPending, startTransition] = useTransitionHook()
返回一个具有两个成员的数组:紧急的大量UI更新
接下来考虑一个所有更新都很紧急的例子,以及这些大量更新是如何影响用户体验的。 比如有一个员工名字列表和一个查找员工的姓名搜索框,这个组件会高亮显示匹配搜索内容的员工姓名。 以下是可能实现的代码:
在组件内部,query是包含查询字符串的状态变量。输入框是一个控制组件-用于在用户输入改变时更新query状态变量。当使用者在快速在输入框内键入查询字段,你可能会注意到键入延迟以及用户界面在明显的时间内没有响应。 👉 为什么会出现这种现象,如何解决呢? 在用户键入时更新输入框的值是一个必须快速执行的紧急任务,更新高亮显示匹配列表是一个繁重且不紧急的任务。大量的非紧急任务落后于轻量的紧急任务。useTransition()钩子能够帮助你区分紧急的UI更新和非紧急的UI更新。
大量的UI更新作为过渡(transitions)
之前已经提高了,你可以使用 useTransition 告诉React哪些UI更新是紧急的(比如更新输入框的值)和哪些UI更新是不紧急的transitions(比如更新高亮匹配查询内容的姓名列表) 💡 我们来对FilterList组件做一下必要的调整: 首先,我们调用
[isPending, startTransition] = useTransition()
钩子来访问startTransition()函数,然后专门这个transition创建了一个保存状态的状态变量。使用了transitionos特性,如果你非常快速地在输入框中键入,你会注意到高亮列表的延迟更新。 React将紧急任务(当用户键入时更新输入框)的更新和非紧急任务(高亮显示过滤内容)的渲染区分开了,这样的操作提升了用户体验。
总结
React中的并发模式(concurrent mode)将紧急任务和非紧急任务区分开,使UI更新更加人性化。在开启React 18并发模式新特性之后,你可以使用useTransition()钩子进而使用startTransition(callback)函数。 useTransition()使你能够将默写更新标记为过渡(transitions):