自学内容网 自学内容网

React useRef 的性能优化

一、介绍

useRef 是 React 中的一个 Hook,用于引用 DOM 元素或存储任何可变的值,而不会触发组件的重新渲染,是一个引用变量。它的设计初衷旨在为那些不需要重新渲染的场景提供一个持久化的、可变的值。

二、工作原理:

若调用 useRef(initialValue) 时,react 会创建一个包含 current 属性的对象,并将 initialValue 赋值给 current,这个对象会在整个组件生命周期内保持不变,不会因为组件的重新渲染而改变,除非手动修改它的值。

当第一次被赋值时,会自动被赋值为初始值,当再次赋值时,它的值不会被更改,永远都表示上一次的旧值,除非使用 current 属性去改变它.

三、与 useState 对比

1. useState:是状态变量,当状态通过 setState 更新时,React 会重新渲染组件,这样新的状态值可以反映在组件的 UI 上。

2. useRef:是引用变量,即使 ref.current 被修改,React 也不会重新渲染组件,它只是在内存中更新了 ref.current 的值,所以不会反映在组件的 UI 上。

四、适用场景

1. 访问和操作 DOM 元素,当某种情况下使焦点自动移动到某个输入框中,而不会重新渲染组件:

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

const App = () => {
  const input = useRef(null);

  // 页面初始化后使 input 元素获得焦点
  useEffect(() => {
    input.current.focus();
  }, []);

  return (
    <div>
      <input ref={input} type="text" />
    </div>
  );
};

export default App;

2. 在处理大量数据或频繁交互时,使用 useRef 可以提高性能。以下是一个滚动事件监听的示例:

import React, { useState, useRef, useEffect } from "react";

const App = () => {
  const [items] = useState(Array.from({ length: 100 }, (_, i) => `Item ${i}`));
  const scrollContainerRef = useRef(null); // 用来存储容器的 ref
  const scrollPositionRef = useRef(0); // 用来存储滚动位置

  useEffect(() => {
    const handleScroll = () => {
      if (scrollContainerRef.current) {
        // 更新 ref,不触发重新渲染
        scrollPositionRef.current = scrollContainerRef.current.scrollTop;
        console.log(`Scroll position: ${scrollPositionRef.current}`);
      }
    };

    const scrollContainer = scrollContainerRef.current;
    if (scrollContainer) {
      // 监听容器的滚动事件
      scrollContainer.addEventListener("scroll", handleScroll);
    }

    return () => {
      if (scrollContainer) {
        // 卸载时移除事件监听器
        scrollContainer.removeEventListener("scroll", handleScroll);
      }
    };
  }, []);

  return (
    <div
      ref={scrollContainerRef}
      style={{
        width: "400px",
        height: "300px",
        overflowY: "scroll",
        border: "1px solid black",
      }}
    >
      <ul>
        {items.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
};

export default App;

五、优势

useRef 不会触发组件的重新渲染,在对大量数据进行处理时可以大大提高性能,在一定程度上避免了不必要的渲染。


原文地址:https://blog.csdn.net/forever__fish/article/details/142464385

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!