React Hooks 之 useRef

当你在React中处理DOM元素或需要在组件渲染之间保持持久性数据时,useRef 成为一项强大的工具。本文将深入探讨 useRef 的用途、工作原理以及如何在React函数组件中正确使用它。

引言

在React中,函数组件通常是无状态的,每次渲染都是独立的,无法通过常规的变量来保存状态。然而,有时我们需要在组件渲染之间保留数据,或者直接操作DOM元素。这就是 useRef 发挥作用的地方。

useRef 是什么?

useRef 是React提供的一个Hook,它返回一个可变的 ref 对象。这个对象有一个 current 属性,可以保存任意可变值,其在组件重新渲染时不会被重置。

用途

1. 获取DOM元素的引用

jsx 复制代码
import React, { useRef, useEffect } from 'react';

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

  useEffect(() => {
    console.log(myRef.current);
    // 这里可以对DOM元素进行操作
    myRef.current.style.color = 'red';
  }, []);

  return (
    <div ref={myRef}>
      Hello, useRef!
    </div>
  );
}

2. 保留持久性数据

jsx 复制代码
import React, { useRef, useEffect } from 'react';

function ExampleComponent() {
  const counterRef = useRef(0);

  useEffect(() => {
    console.log('Current counter value:', counterRef.current);
  }, []);

  const incrementCounter = () => {
    counterRef.current += 1;
  };

  return (
    <div>
      <p>Counter: {counterRef.current}</p>
      <button onClick={incrementCounter}>Increment</button>
    </div>
  );
}

3. 避免触发不必要的重新渲染

jsx 复制代码
import React, { useState, useRef, useEffect } from 'react';

function ExampleComponent() {
  const [data, setData] = useState([]);
  const dataRef = useRef(data);

  useEffect(() => {
    // 通过dataRef.current来访问数据,而不会触发重新渲染
    console.log('Data:', dataRef.current);
  }, []);

  const updateData = () => {
    const newData = [...dataRef.current, Math.random()];
    dataRef.current = newData;
    setData(newData);
  };

  return (
    <div>
      <button onClick={updateData}>Update Data</button>
    </div>
  );
}

工作原理

  • 当 useRef 第一次调用时,它会创建一个包含 current 属性的对象,并将其初始值设置为传递给 useRef 的参数。
  • useRef 创建的引用对象在组件重新渲染时不会被重置。
  • 通过访问 ref.current 来获取或修改引用对象的值。

总结

useRef 是React中一个强大而灵活的工具,可用于在函数组件中处理DOM元素、保存持久性数据,并优化性能。通过了解其基本用法和工作原理,你可以更好地利用 useRef 来满足各种组件级别的需求。无论是操作DOM,管理状态,还是优化渲染,useRef 都是一个非常有用的工具。

相关推荐
亿元程序员2 小时前
太牛了!这AI做出来的游戏,居然还能变现!
前端
hellice2 小时前
闪传 FlashDrop 实战:我用 300 行 Node 代码做了个「4 位取件码」临时文件中转站
前端·产品
用户0829773260052 小时前
RTX 5500 MIG 踩坑记录:切分之后模型跑不起来,排错整整一下午
前端
Lank_M2 小时前
AI 放大后的图更清楚,但它不能当原图入库
前端
Swot2 小时前
SvelteKit 数据流研究:`+page.js` 和 `+page.server.js` 到底谁在跑,数据又去了哪儿
前端·后端
用户4147679304152 小时前
Windows 触摸屏上 Swiper 轮播滑不动?可能是内部滚动容器抢走了你的手势
前端
张明君644512 小时前
从一个 Referer 引发的 403,到 SSR 服务失稳:Astro 流式渲染与缓存失效分析
前端
律宏阔2 小时前
微信小程序 + Taro + TDesign 去掉 [&&&],让普通 Tailwind 类接管局部样式
前端·微信小程序·taro
费曼学习法2 小时前
把 3 个内部服务封装成 MCP Server 的工程复盘:进程模型、超时与错误契约
前端
Captaincc2 小时前
转译:《软件工程师现在该怎么办》
前端·后端·ai编程