试试 useTransition 钩子吧

2024-04-07 10:53:39

阅读:1275
标签:reacthtml

来试试 useTransition 钩子吧

前言

  • 默认情况下,React 中的所有更新都被视为紧急。当快速更新大量数据时不可避免的回出现卡顿
    图 1

  • 但是,从 React 18 和新的并发功能开始,我们可以将某些更新标记为可中断、非紧急。这对于大量 UI 更新(例如过滤大列表)特别有用
    图 2

useTransition 介绍

useTransition()是 react18 内置一个钩子,可让我们访问 React 组件内部的并发模式功能

import { useTransition } from "react";
const [isPending, startTransition] = useTransitionHook();

// isPending:表示等待中
// startTransition(callback):允许您将内部的任何 UI 更新标记 callback 为过渡

// 为了使用useTransition()钩子正常工作,请确保启用并发模式
import React from "react";
import ReactDOM from "react-dom";

const App = () => {
  return <div>Hello, React 18!</div>;
};

const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(<App />);

应用场景

假设我们有一个员工姓名列表,管理员在页面中查询的输入的姓名。查询结果高亮显示匹配到的关键字

  • 过去的场景我们可能是这样实现的
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>
  );
}

当在输入字段中快速输入查询。你会注意到打字滞后,并且用户界面在一段时间内感觉没有响应。
为什么会出现这种情况,又该如何解决呢?
当用户键入时更新输入字段值是一项必须快速执行的紧急任务。然而,通过突出显示匹配项来更新列表是一项繁重但不紧急的任务。
繁重的非紧急任务会减慢轻紧急任务的速度。这时候就需要 useTransition 帮助我们

  • 优化方案
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还是原来的组件不需要变化变化 */}
        <ListItem key={i} name={name} highlight={highlight} />
      ))}
    </div>
  );
}

React 中的并发模式可让您将紧急任务与非紧急任务分开,使 UI 更新更加用户友好。启用新的并发模式后,就可以使用 useTransition()hook 来访问 startTransition(callback)函数了

评论:

    X

    备案号 皖ICP备19021899号-1  技术支持 © 947968273@qq.com