发布于 2026-01-06 10 阅读
0

掌握 React 和 TypeScript 中的 'useRef':'useRef' 的 4 个不同用例

掌握 React 和 TypeScript 中的 'useRef':'useRef' 的 4 个不同用例

在 React 中,useRef 是一个功能强大的 Hook,它允许开发者与 DOM 交互并管理可变值,而无需触发页面重新渲染。当与 TypeScript 结合使用时,它的功能更加强大,能够提供类型安全并防止常见的运行时错误。本文将探讨 useRef 在 React 中的各种应用场景,重点介绍如何在 TypeScript 项目中高效使用它。

了解 useRef:
React 中的 useRef hook 提供了一个可变对象,称为“ref”。这个 ref 可以保存对 DOM 元素或其他任何值的引用,并且在渲染过程中保持不变。与状态变量不同,更改 ref 的值不会触发组件的重新渲染,这使得它非常适合某些特定场景。

基本用法
以下是如何在函数式组件中使用 useRef 的方法:

import React, { useRef } from 'react';

function MyComponent() {
  const myRef = useRef(null);

  // Accessing the current value of the ref
  console.log(myRef.current);

  return <div ref={myRef}>Hello, useRef!</div>;
}
Enter fullscreen mode Exit fullscreen mode

在上面的例子中,我们创建了一个名为 myRef 的引用,并使用 ref 属性将其附加到一个 DOM 元素上。您可以使用 myRef.current 访问该引用的当前值。

React 和 TypeScript 中 useRef 的使用场景
1. 访问 DOM 元素
useRef 最常见的使用场景之一是直接访问 DOM 元素。这对于诸如聚焦输入字段或测量元素尺寸等任务非常有用:

import React, { useRef, useEffect } from 'react';

function AutoFocusInput() {
  const inputRef = useRef<HTMLInputElement | null>(null);

  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  return <input ref={inputRef} />;
}
Enter fullscreen mode Exit fullscreen mode

在这个例子中,inputRef 允许我们在组件挂载时聚焦输入元素,而无需状态变量来触发重新渲染。

2. 存储先前值
useRef 可用于存储和比较不同渲染之间的先前值。这对于检测 props 或 state 的变化非常有用:

import React, { useRef, useEffect } from 'react';

function ValueChangeDetector(props: { value: number }) {
  const prevValueRef = useRef<number | undefined>();

  useEffect(() => {
    if (prevValueRef.current !== undefined && prevValueRef.current !== props.value) {
      console.log('Value changed:', prevValueRef.current, '->', props.value);
    }

    prevValueRef.current = props.value;
  }, [props.value]);

  return <div>{props.value}</div>;
}
Enter fullscreen mode Exit fullscreen mode

在这里,prevValueRef 存储 value prop 的先前值,使我们能够比较它并在它发生变化时采取操作。

3. 存储非托管值
useRef 可用于存储那些更改时不会触发重新渲染的值。这对于缓存耗时的计算或不属于组件状态的值非常有用:

import React, { useRef, useState } from 'react';

function ExpensiveComponent() {
  const expensiveValueRef = useRef<number>(0);
  const [count, setCount] = useState<number>(0);

  const calculateExpensiveValue = () => {
    if (expensiveValueRef.current === 0) {
      // Perform expensive calculation
      expensiveValueRef.current = /* ... */;
    }
    return expensiveValueRef.current;
  };

  return (
    <div>
      <p>Expensive Value: {calculateExpensiveValue()}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

在这个例子中,expensiveValueRef 存储了昂贵计算的结果,确保计算只发生一次。

4. 与第三方库交互
当将 React 与依赖可变值的第三方库或 API 集成时,可以使用 useRef 来维护引用并安全地与这些库交互:


import React, { useRef, useEffect } from 'react';
import { Chart } from 'chart.js';

function ChartComponent(props: { data: number[] }) {
  const chartRef = useRef<HTMLCanvasElement | null>(null);
  const chartInstance = useRef<Chart | null>(null);

  useEffect(() => {
    if (chartRef.current) {
      chartInstance.current = new Chart(chartRef.current, {
        type: 'line',
        data: {
          labels: [...Array(props.data.length).keys()],
          datasets: [
            {
              label: 'Data',
              data: props.data,
              borderColor: 'blue',
            },
          ],
        },
      });
    }

    return () => {
      if (chartInstance.current) {
        chartInstance.current.destroy();
      }
    };
  }, [props.data]);

  return <canvas ref={chartRef} />;
}
Enter fullscreen mode Exit fullscreen mode

这里,chartRef 保存着对 canvas 元素的引用,chartInstance 保存着对 Chart 实例的引用。我们在 useEffect 钩子函数中安全地创建和销毁图表。

结论:
React 中的 useRef hook 与 TypeScript 结合使用时,是一个强大的工具,它允许你在保持类型安全的同时,高效地处理可变值并与 DOM 交互。理解 useRef 的各种用例和最佳实践将有助于你编写更简洁、更高效的 React 组件。无论你是管理 DOM 元素、跟踪历史值、缓存数据还是与外部库交互,useRef 都是你 React 工具包中不可或缺的宝贵工具。

文章来源:https://dev.to/kirubelkinfe/mastering-useref-in-react-with-typescript-4- Different-use-cases-for-useref-2a87