讲师中心 微信公众号
AI工具推荐 视频效率加速

如何正确在 React 中动态创建多个 useRef 实例以实现滚动定位功能

胖浩姑娘_4815

胖浩姑娘_4815

发布时间:2026-01-16 12:57:16

|

805人浏览过

|

来源于php中文网

原创

如何正确在 React 中动态创建多个 useRef 实例以实现滚动定位功能

react 的 `useref` 必须在组件或自定义 hook 的顶层调用,不能在循环、条件语句或回调中使用;本文将展示如何通过单个 `useref` 管理多个 dom 元素引用,并安全实现基于标签的滚动跳转。

该错误的根本原因在于违反了 React Hooks 的核心规则:Hooks 必须始终在顶层调用,且调用顺序必须稳定。你在 useDivRefs 中对 labels.forEach 内部调用 useRef(null),相当于在每次迭代中“动态”调用 Hook —— 这不仅破坏了调用顺序的可预测性,也使 React 无法正确关联 ref 与组件渲染周期,因此触发 react-hooks/rules-of-hooks ESLint 报错。

✅ 正确做法是:用一个 useRef 存储数组(或对象),并在 ref 回调函数中动态赋值。这种方式既符合 Hook 规则,又能灵活映射任意数量的 DOM 节点。

以下是推荐的完整实现方案:

Article To Html
Article To Html

文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。

下载
import { useRef, useEffect } from 'react';

// ✅ 安全的自定义 Hook:返回带 ref 映射能力的对象
const useDivRefs = (labels) => {
  const refs = useRef({});

  // 初始化 refs 对象(仅在首次渲染时设置 key,避免重复覆盖)
  useEffect(() => {
    labels.forEach((label) => {
      const targetId = label.replace(/\s+/g, '');
      if (!(targetId in refs.current)) {
        refs.current[targetId] = null;
      }
    });
  }, [labels]);

  return refs;
};

const MyComponent = () => {
  const labels = ['div 1', 'div 2', 'div 3'];

  // 使用自定义 Hook 获取统一 ref 容器
  const divRefs = useDivRefs(labels);

  // 滚动到指定标签区域的辅助函数
  const scrollToSection = (label) => {
    const targetId = label.replace(/\s+/g, '');
    const el = divRefs.current[targetId];
    if (el) {
      el.scrollIntoView({ behavior: 'smooth' });
    }
  };

  return (
    <div>
      {/* 导航栏 */}
      <nav>
        {labels.map((label) => (
          <button
            key={label}
            onClick={() => scrollToSection(label)}
            style={{ margin: '0 8px' }}
          >
            Go to {label}
          </button>
        ))}
      </nav>

      {/* 可滚动内容区 */}
      <main>
        {labels.map((label, i) => {
          const targetId = label.replace(/\s+/g, '');
          return (
            <section
              key={label}
              id={targetId} // 同时提供 id,兼容锚点跳转
              ref={(el) => {
                if (el) divRefs.current[targetId] = el;
              }}
              style={{
                minHeight: '100vh',
                padding: '40px 20px',
                backgroundColor: i % 2 === 0 ? '#f9f9f9' : '#fff',
              }}
            >
              <h2>{label}</h2>
              <p>This is section {i + 1}. Scroll down to see more.</p>
            </section>
          );
        })}
      </main>
    </div>
  );
};

export default MyComponent;

? 关键要点说明:

  • useRef({}) 创建一个持久化的可变对象容器,其 .current 属性可随时写入任意键值(如 refs.current['div1'] = domNode);
  • 使用 ref 回调函数(ref={(el) => {...}})而非 useRef() 多次调用,确保每个元素挂载/卸载时精准更新引用;
  • useEffect 用于初始化 refs.current 的键结构(可选,提升代码健壮性);
  • 支持 id 属性 + scrollIntoView 组合,兼顾语义化 HTML 和无障碍访问(a11y)。

⚠️ 注意事项:

  • 不要直接在 ref 回调中调用 setState(如 setX(...)),否则可能引发无限循环;
  • 若需在 useEffect 中读取这些 ref,请添加依赖项 divRefs 并使用 divRefs.current 访问;
  • 避免在服务端渲染(SSR)环境中依赖 ref.current 值(此时为 null),应配合 useEffect 或 if (typeof window !== 'undefined') 判断。

通过这种模式,你既能优雅管理动态数量的 DOM 引用,又完全遵守 React 的 Hook 规范,为后续实现平滑滚动、动画联动或焦点控制打下坚实基础。

热门AI工具

更多
Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1678

2024.03.01

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

738

2025.12.04

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

11705

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

5507

2024.08.14

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

2516

2025.12.25

JavaScript中的typeof用法
JavaScript中的typeof用法

在JavaScript中,typeof是一个用来确定给定变量的数据类型的操作符。可以用来确定一个变量是字符串、数字、布尔值、函数、对象或undefined的数据类型。更多关于typeof用法相关文章,详情请看本专题下面的文章,php中文网欢迎大家前来学习。

7787

2023.11.23

DOM是什么意思
DOM是什么意思

dom的英文全称是documentobjectmodel,表示文件对象模型,是w3c组织推荐的处理可扩展置标语言的标准编程接口;dom是html文档的内存中对象表示,它提供了使用javascript与网页交互的方式。想了解更多的相关内容,可以阅读本专题下面的文章。

6501

2024.08.14

PixTV官网入口地址合集
PixTV官网入口地址合集

本专题汇总了 PixTV AI 一站式视频创作平台的官方入口与使用教程。无需下载软件,浏览器直接访问即可使用。平台将剧本、图像、视频、声音与剪辑整合在“无限画布”中,接入 GPT Image 2.5、Seedance 2.5 等头部模型。本专题整理了从新建画布、角色锚定、分镜拆分到视频生成与导出的完整操作指南,助你快速上手 AI 短剧与漫剧创作。

60

2026.10.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 12.2万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn