如何在React中使用 useTransition()hook函数的教程
如何使用React useTransition()hook
有些UI更新应该尽可能快地执行(在输入框中打字,从下拉菜单中选择一个值),而其他的UI更新可以有较低的优先级(过滤一个列表)。
直到现在,React还没有提供一个工具来确定UI更新的优先级。
幸运的是,从React 18开始(截至2021年6月的alpha版本),你可以启用并发模式--它允许你将UI更新标记为高优先级或可中断的低优先级。
在这篇文章中,你将学习如何使用useTransition()
钩子将UI更新标记为低优先级,这对大量非紧急更新特别有用。
1.useTransition() 钩子
默认情况下,React中的所有更新都被认为是紧急的。当快速更新被重度更新拖慢时,这可能会产生一个问题。
然而,从React 18和新的并发功能开始,你可以将一些更新标记为可中断的和非紧急的--所谓的过渡期。这对繁重的UI更新特别有用,比如过滤一个大列表。
useTransition()
是让你在React组件内部访问并发模式功能的钩子。
调用const [isPending, startTransition] = useTransitionHook()
,返回一个包含2个项目的数组。
isPending
: 表示过渡正在等待startTransition(callback)
: 允许你将callback
里面的任何UI更新标记为过渡。
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} />;
}
为了使用useTransition()
钩子,请确保启用并发模式。
2.重度UI更新为紧急
让我们考虑一个例子,当所有的更新都是紧急的,它是如何影响用户体验的。
你有一个员工名字的列表,以及一个用户引入查询的输入字段。该组件突出显示员工姓名中的查询匹配。
下面是一个可能的实现:
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>
);
}
<FilterList names={names} />
接受一个大的姓名数组。在该组件中, 是包含查询字符串的状态变量。输入字段是一个query
受控组件,当用户输入时更新 状态变量。query
打开演示,在输入栏中快速输入一个查询。你会注意到打字滞后,用户界面在明显的时间内感觉没有反应。
为什么会发生这种情况,以及如何解决?
当用户输入时,更新输入字段的值是一项紧急任务,必须快速执行。然而,通过高亮显示匹配信息来更新列表是一项繁重但不紧急的任务。
沉重的非紧急任务拖慢了轻度紧急任务的速度。
useTransition()
钩子可以帮助你区分紧急和非紧急的UI更新。
3.重的UI更新作为过渡
正如已经提到的,你可以使用useTransition()
钩子来让知道React哪些UI更新是紧急的(比如更新输入字段的值),哪些是非紧急的过渡(比如更新名字列表以突出查询)。
让我们对<FilterList>
组件进行必要的调整。
首先,让我们调用[isPending, startTransition] = useTransition()
钩子以获得对startTransition()
函数的访问。其次,让我们创建一个状态变量来保存专门用于过渡的查询状态值。
import { 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" />
{names.map((name, i) => (
<ListItem key={i} name={name} highlight={highlight} />
))}
</div>
);
}
使用过渡功能打开演示。如果你在输入框中快速输入一个查询,你会注意到在列表内突出显示查询时有延迟。
React已经将紧急任务(当用户输入时更新输入字段)的渲染与非紧急任务(在列表内突出显示查询)分开。这样的方法提供了更好的用户体验。
4.总结
React中的并发模式可以让你把紧急任务和非紧急任务分开,使UI更新更方便用户使用。
转载自:https://juejin.cn/post/7125999032870109197