【useDeferredValue Hook】将某个值的更新延迟,平衡高优先级和低优先级更新

目录

  • 前言
  • 语法
  • 使用场景
  • 示例:使用 `useDeferredValue` 优化列表渲染
  • `useDeferredValue`和防抖节流的区别

前言

useDeferredValue 是 React 18 引入的一个 Hook,用于优化渲染性能。它的主要作用是将某个值的更新延迟,以便在繁忙的渲染过程中优先处理更重要的更新。这在处理高优先级更新(如用户输入)和低优先级更新(如渲染大量数据)时非常有用。

语法

import { useState, useDeferredValue } from "react";

function SearchPage() {
  const [query, setQuery] = useState("");
  const deferredQuery = useDeferredValue(query);
  // ...
}

参数:

  • value: 你想延迟的值,可以是任何类型。

返回值:

  • 在组件的初始渲染期间,返回的 延迟更新的值 与传入的 value 相同。
  • 组件更新期间,React 会先尝试使用旧值进行重新渲染(因此它将返回旧值),然后再在后台会用新值进行另一个重新渲染(这时它将返回更新后的值)。

使用场景

  • 延迟更新:当你有一个计算量较大的值(如过滤后的列表),并且希望在不阻塞高优先级更新的情况下延迟更新。
  • 优化性能:在渲染大量数据时,避免阻塞用户交互(如输入框的输入)。

示例:使用 useDeferredValue 优化列表渲染

以下是一个示例,展示如何使用 useDeferredValue 来延迟更新一个过滤后的列表,同时保持输入框的响应性。

import { useState, useDeferredValue, useMemo, memo } from 'react';

interface Props {
  items: string[];
}

/**
 * 创建一个 memoized 版本的 List 组件 
 * 输入框输入时,父子组件都会重新渲染
 * 使用 memo 函数,当 props 未改变时,造成子组件不必要的重新渲染。
 */
const List = memo(function ({ items }: Props) {
  console.log('List render');
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
})

export default function Test() {
  const [inputValue, setInputValue] = useState('');
  // 生成一个延迟更新的值
  const deferredInputValue = useDeferredValue(inputValue);

  // 使用 useMemo 缓存 items 数组
  const items = useMemo(() => {
    // 模拟一个耗时的过滤操作
    const startTime = performance.now();
    while (performance.now() - startTime < 100) {
      // 阻塞 100ms
    }
    return Array.from({ length: 10000 }, (_, i) => `Item ${i + 1}`).filter(
      (item) => item.includes(deferredInputValue)
    );
  }, [deferredInputValue]); // 只有当 deferredInputValue 变化时,才会重新计算 items

  return (
    <div>
      <h1>useDeferredValue 示例</h1>
      <input
        type="text"
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
        placeholder="输入过滤条件"
      />
      <List items={items} />
    </div>
  );
}

useDeferredValue和防抖节流的区别

  • 与防抖或节流不同,useDeferredValue不需要选择任何固定延迟时间, 延迟时间和用户电脑的性能有关。
  • useDeferredValue执行的延迟重新渲染默认是可中断的。如果 React 正在重新渲染一个大型列表,但用户进行了另一次键盘输入,React 会放弃该重新渲染,先处理键盘输入,然后再次开始在后台渲染。

你可能感兴趣的:(React,React,延迟更新,前端)