likes
comments
collection
share

React 'useRef' 在TS中的四种应用场景

作者站长头像
站长
· 阅读数 25

在 React 中,useRef 是一个多功能hook,允许开发人员与 DOM 交互并管理可变值,而不会触发刷新。当在 TypeScript 中使用时,它将变得更加强大,可提供类型安全并防止常见的运行时错误。在本文中,我们将探讨 React 中 useRef 的各种用例,重点是如何在 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>;
}

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

TS中React useRef的应用

1.访问DOM元素

useRef 最常见的用例之一是直接访问 DOM 元素。这对于input聚焦输入字段或获得元素尺寸等任务非常有用:

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

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

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

  return <input ref={inputRef} />;
}

在本例中,inputRef 能够在组件挂载时聚焦输入元素,而不需要状态变量来触发重新渲染。

2.变量值缓存

useRef 可用于存储和比较不同渲染中的先前值。这对于检测propsstate的变化非常有用:

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

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

  useEffect(() => {
    prevValueRef.current = props.value;

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

  return <div>{props.value}</div>;
}

prevValueRef 保存了props的前一个值,以便进行比较,并在props发生变化时处理任务。

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>
  );
}

在本例中,effensiveValueRef 存储了计算结果,确保计算只发生一次。

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} />;
}

chartRef 是对画布元素的引用,chartInstance 是对图表实例的引用。在 useEffect 钩子中安全地创建和销毁图表。

总结

React 中的 useRef 钩子与 TypeScript 结合使用时,是一种强大的工具,可让你处理可变值并高效地与 DOM 交互,同时保持类型安全。了解 useRef 的各种用例和最佳实践将有助于编写更简洁、性能更强的 React 组件。

转载自:https://juejin.cn/post/7274542847658557480
评论
请登录