react 中 ref 管理列表

news2025/1/16 17:44:33

背景

最近在看 react 新的官方文档 的时候,看到这么一个标题,How to manage a list of refs using a ref callback,就是一个图片的列表,类似这样
在这里插入图片描述
然后点击按钮的时候,通过 scrollIntoView 这个 api 来让他滚动,要使用这个 api 我们就要通过 ref 拿到这个 dom 元素,但是如果是一个列表的话,我们要怎么去做这个事情呢?难道循环用 useRef 申明一堆 ref 引用吗?显然不合理。

问题

文档里头还给了一段代码

<ul>
  {items.map((item) => {
    // Doesn't work!
    const ref = useRef(null);
    return <li ref={ref} />;
  })}
</ul>

显然这段代码肯定是不可行的,都跑不起来,因为 hooks 他只能在组件的最顶层,是不可以放在判断语句或者循环语句里头的

解决方法 ref callback

ref callback 就是给 ref 传一个函数,react 在设置 ref 的值的时候,会自动去调用这个函数,然后我们就可以通过这个函数去维护一个数组或者一个 map,从而实现我们需要多个 ref 的需求。听着好像挺复杂的,上代码吧

const RefListDemo = () => {
  const itemsRef = useRef(null)

  function getMap() {
    if (!itemsRef.current) {
      itemsRef.current = new Map()
    }
    return itemsRef.current
  }

  function scrollToId(itemId) {
    const map = getMap()
    const node = map.get(itemId)
    node.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'center',
    })
  }

  return (
    <>
      <nav>
        <button onClick={() => scrollToId(0)}>Tom</button>
        <button onClick={() => scrollToId(5)}>Maru</button>
        <button onClick={() => scrollToId(9)}>Jellylorum</button>
      </nav>
      <div>
        <ul
          style={{
            listStyle: 'none',
            display: 'flex',
            width: 300,
            overflow: 'scroll',
            flexWrap: 'nowrap',
          }}
        >
          {catList?.map((cat) => (
            <li
              key={cat.id}
              style={{ marginLeft: 12 }}
              // 用这样的方式,就可以拿到每个节点,并进行维护了
              ref={(node) => {
                const map = getMap()
                node ? map.set(cat.id, node) : map.delete(cat.id)
              }}
            >
              <img src={cat.imageUrl} alt={'Cat #' + cat.id} />
            </li>
          ))}
        </ul>
      </div>
    </>
  )
}

上面代码的关键就在这里,我们可能平时传递 ref 的时候,都是传递一个具体的引用,好像都比较少用到这种传递函数的方式,官方是使用 map 维护,用列表也是一样的逻辑。

ref={(node) => {
	const map = getMap()
	node ? map.set(cat.id, node) : map.delete(cat.id)
}}

代码示例我放到这里啦。如果有兴趣的话,可以来这里试一下

先有 Dom 再滚动

在文档里头还有说到另一个问题,像这样在输入框输入,然后插入到队列里头,然后还是用 scrollIntoView 这个 api 滚动到新插入的结点的位置,但是这就可能会有一个问题,我们 setTodos 之后就执行了 scrollIntoView

但是我们都知道在 react 里头,更新 state 都是在队列里头更新的,并不是每次 setState 的时候就会立即更新, 所以更新上去的 dom 可能还没插入进去,我们就执行了 scrollIntoView,他不是一个一定会出现的问题,但是如果在实现类似的需求的时候,我们就得意识到这是个潜在的问题,

setTodos([ ...todos, newTodo]);
listRef.current.lastChild.scrollIntoView();

在这里插入图片描述

flushSync

react-dom 里头提供了一个 api,可以让我们实现同步更新 dom, 就是 flushSync,在 setTodos 的时候,用 flushSync 就能避免这样的问题发生

flushSync(() => {
  setTodos([ ...todos, newTodo]);
});
listRef.current.lastChild.scrollIntoView();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/10246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python生成模拟微信气泡图片

0. 起因 众所周知&#xff0c;借刀杀人最为致命&#xff0c;聊天也是如此。 最近我的群聊画风逐渐变味&#xff1a; 当然&#xff0c;这种图片的生产成本很低&#xff0c;只需在设置页关闭昵称显示&#xff0c;把聊天背景重置为灰色&#xff0c;然后利用截图工具截图&#xf…

【金融项目】尚融宝项目(十三)

25、充值 25.1、需求介绍 25.1.1、投资人充值 **1、需求描述 ** 标的产生后&#xff0c;平台展示标的&#xff0c;投资人就可以在平台投资标的&#xff0c;获取收益&#xff1b;投资人投资标的必须满足以下条件&#xff1a; 充值过程与绑定过程一致&#xff0c;也是在平台发…

Delphi 11.2 Alexandria程序集代码

Delphi 11.2 Alexandria程序集代码 高DPI VCL设计器-VCL设计器现在在设计时使用类似Microsoft Windows的样式&#xff0c;这意味着除非禁用此功能&#xff0c;否则设计器中的控件始终使用此样式绘制。此样式与Windows当前使用的浅色或深色主题相匹配。 编辑器选项卡-在版本11.2…

【3D目标检测】Frustum PointNets for 3D Object Detection from RGB-D Data

目录概述细节网络结构视锥候选框3D实例分割边界框参数回归损失函数概述 首先本文是基于图像和点云的&#xff0c;属于早期的模态融合的成果&#xff0c;是串行的算法&#xff0c;而非并行的&#xff0c;更多的是考虑如何根据图像和点云这两个模态的数据进行3D目标检测。 提出动…

亚马逊平台不给力?来Starday,告诉你什么是真正的高阶玩法

距2021年的亚马逊封号潮已经过去了一段时间&#xff0c;但其影响却依然在跨境电商行业间回荡。从4月份起&#xff0c;亚马逊就开始对违反平台规则的卖家进行封号。此后打击规模持续扩大&#xff0c;到6月中下旬&#xff0c;深圳一批头部卖家均被亚马逊平台下架&#xff0c;遭到…

Coverage-based Greybox Fuzzing as Markov Chain

AFLFast: Coverage-based Greybox Fuzzing as Markov Chain 一、论文阅读 论文来自CCS2016 作者&#xff1a;Marcel Bhme 模糊测试领域巨佬 Abstract 基于覆盖的灰盒模糊测试 Coverage-based Greybox Fuzzing (CGF)。大多数测试用例执行少数高频路径&#xff0c;制定策略倾…

浪潮信息工程师:谈一谈设备透传虚拟机启动慢背后的原因及其优化方法 | 第 51 期

本周「龙蜥大讲堂」预告来啦&#xff01;龙蜥社区邀请了浪潮信息操作系统研发工程师崔士伟分享《设备透传虚拟机的快速启动优化》&#xff0c;快来扫码入群&#xff0c;预定前排小板凳观看直播吧&#xff01; 直播主题及内容介绍 直播主题&#xff1a;设备透传虚拟机的快速启…

360+城市空气质量指数-日度数据、良好天数统计(2001-2022年)

360城市空气质量指数-日度数据、良好天数统计&#xff08;2001-2022年&#xff09; 城市空气质量指数-日度数据、良好天数统计 1、包括&#xff1a;360个城市 2、时间&#xff1a;2001.1-2022.1月 3、样本量&#xff1a;1371937条 4、数据来源&#xff1a;空气质量在线…

使用Excel 表示汽车、摩托车10年免检时间、非常清晰。

1&#xff0c;汽车摩托车10年内年检问题 根据最新的国家法律&#xff1a; http://www.wenjiang.gov.cn/wjzzw/c152333/2022-09/30/content_66efe4febb8040758f3f079cf0baa310.shtml 搜索了下&#xff0c;找到了成都的规定&#xff1a; 近日&#xff0c;公安部、市场监管总局…

中电海康-中电52所面经

中电海康&#xff0c;中电52所面经中电海康面经一面&#xff08;电话面&#xff09;二面&#xff08;现场面&#xff09;自我回顾中电海康面经 一面&#xff08;电话面&#xff09; Redis的使用和配置多线程的使用&#xff0c;线程池的使用SpringBoot的核心注解和流程AOP IOC …

java项目-第133期ssm物流服务管理平台系统-java毕业设计

java项目-第133期ssm物流服务管理平台系统-毕业设计 【源码请到资源专栏下载】 今天分享的项目是《物流服务管理平台系统》 该项目分为前台和后台。主要分成三个角色&#xff1a;游客、普通管理员、管理员三个角色。 游客就是用户&#xff0c;只要是访问系统前台的用户都可以算…

华为防火墙的四种智能选路方式

FW支持四种智能选路方式&#xff0c;不同的智能选路方式可以满足不同的需求&#xff0c;管理员可以根据设备和网络的实际情况进行选择。 表1 智能选路方式 智能选路方式 定义 根据链路带宽负载分担 FW按照带宽比例将流量分配到各条链路上。带宽大的链路转发较多的流量&…

【我的渲染技术进阶之旅】基于Filament渲染引擎绘制一个不停旋转的彩色矩形

一、绘制三角形回顾 在上一篇博客 【我的渲染技术进阶之旅】Google开源的基于物理的实时渲染引擎Filament源码分析:Android版本的Filament第一个示例:sample-hello-triangle 中,我们分析了如何使用Filament来绘制一个三角形,效果如下所示,有一个不停旋转的彩色三角形: …

“外卷”的羽绒服

【潮汐商业评论/ 原创】 2022年的寒潮要比以往来得更早。 “你能想到我今年的第一件羽绒服竟然是在十一期间买的。”没等上“双十一”的车&#xff0c;Eva在国庆期间就已下单了“秋天的第一件羽绒服”。把保暖战线拉长的也不止Eva一个人&#xff0c;据浙商证券研报显示&#…

SpringBoot原理初探以及第一个SpringBoot程序【SpringBoot】

文章目录一.SpringBoot1.1 Spring和SpringBoot1.2 本阶段学习任务1.3 微服务架构二.搭建一个SpringBoot程序2.1 新建SpringBoot项目&#xff08;官方&#xff09;2.2 正常创建SpringBoot项目2.3 项目结构2.4 启动项目2.5 写一个接口HelloControlier2.6 原理2.7 更改配置三.原理…

Plaxis Python 命令流自动化处理、岩土工程渗流问题之有限单元法

目录 岩土工程渗流问题之有限单元法&#xff1a;理论、模块化编程实现、开源程序手把手实操应用 基于python命令流及代码的Plaxis自动化建模与典型案例实践应用 岩土工程渗流问题之有限单元法&#xff1a;理论、模块化编程实现、开源程序手把手实操应用 有限单元法在岩土工程…

NC65 sql server 报数据库“xxx”事务日志已满 的解决方案。

近日公司的NC系统在做薪资发放的计算是&#xff0c;报了如下图的错误&#xff1a; 如何解决解决事务日志已满的问题&#xff08;SQL Server 错误 9002&#xff09;这个问题呢&#xff1f; 微软给的方案 适用于&#xff1a; SQL Server&#xff08;所有受支持的版本&#xf…

IPWorks Encrypt Delphi强加密的一整套组件

IPWorks Encrypt Delphi强加密的一整套组件 通过主要加密标准实现强加密的一整套组件。 IPWorks Encrypt是一个广泛的组件库&#xff0c;允许您通过主要的加密标准(包括S/MIME、OpenPGP、TripleDES、TwoFish、RSA、AES等)对文件、电子邮件、文档和消息进行加密和解密。 IPWorks…

整理了173家国企清单,跳槽必备!

我这里汇总了一些计算机专业可以加入的国企&#xff0c;分享给求职的小伙伴们&#xff0c;内容很多&#xff0c;先收藏再看&#xff01; 一、首选证券公司 各省基本都有一所证券公司&#xff0c;沿海省份集中在税前30-40万左右&#xff0c;内地集中在20-30万。很少加班&#…

二、使用java简单操作kafka

系列文章目录 1.kafka基本原理 文章目录系列文章目录一、搭建一个kafka的demo2.引入依赖3.创建对应的类二、生产者2-1发送到指定分区&#xff0c;等待消息发送成功&#xff08;会阻塞&#xff09;2-2发送到指定分区&#xff0c;异步方式2-3其余两种情况&#xff0c;不指定分区…