react18中在列表项中如何使用useRef来获取每项的dom对象

在react中获取dom节点都知道用ref,但是在一个列表循环中,这样做是行不通的,需要做进一步的数据处理。

实现效果

需求:点击每张图片,当前图片出现在可视区域。
请添加图片描述

代码实现

.box{border: 1px solid #000;list-style: none;padding: 0;font-size: 0;width: 600px;white-space: nowrap;overflow: hidden;
}
.box li{display: inline-block;padding: 10px;}
.active{border: #000 1px solid;
}
.img{width:80px;height:80px;display: block;
}
  • 核心代码
import { useEffect, useState, useRef } from "react";
import { flushSync } from "react-dom";
import "./compref.css";
function CompRef() {const [catLists, setCatLists] = useState([]);const [index, setIndex] = useState(0);const itemsRef = useRef(null);useEffect(async () => {const getData = await fetch("https://xxxxx");const data = await getData.json();const lists = data.map((item, index) => ({ id: index, url: item.url }));setCatLists(lists);}, []);function getMap() {if (!itemsRef.current) {// 首次运行时初始化 Map。itemsRef.current = new Map();}return itemsRef.current;}return (<><div>CompRef</div><ul className="box">{catLists.map((item, i) => (<likey={item.id}className={index === i && "active"}onClick={() => {setIndex(i);const map = getMap();const node = map.get(index);node.scrollIntoView({behavior: "smooth",block: "nearest",inline: "center",});}}ref={(node) => {const map = getMap();if (node) {map.set(item.id, node);} else {map.delete(item.id);}}}><img className="img" src={item.url} alt="" /></li>))}</ul></>);
}
export default CompRef;

思维扩展

需求:点击下一张按钮,图片出现在可视区域。

  • 实现效果
    请添加图片描述
  • 代码实现
import { useEffect, useState, useRef } from "react";
import { flushSync } from "react-dom";
import "./compref.css";
function CompRef() {const [catLists, setCatLists] = useState([]);const [index, setIndex] = useState(0);const itemsRef = useRef(null);useEffect(async () => {const getData = await fetch("https://xxxxxxxxxxxxxxxxxxx");const data = await getData.json();const lists = data.map((item, index) => ({ id: index, url: item.url }));console.log("🚀 ~ useEffect ~ data:", lists);setCatLists(lists);}, []);function getMap() {if (!itemsRef.current) {// 首次运行时初始化 Map。itemsRef.current = new Map();}return itemsRef.current;}return (<><div>CompRef</div><buttononClick={() => {setIndex(index);if (index < catLists.length - 1) setIndex(index + 1);else setIndex(0);const map = getMap();const node = map.get(index);console.log("🚀 ~ CompRef ~ node:", node);node.scrollIntoView({behavior: "smooth",block: "nearest",inline: "center",});}}>click</button><ul className="box">{catLists.map((item, i) => (<likey={item.id}className={index === i && "active"}ref={(node) => {const map = getMap();if (node) {map.set(item.id, node);} else {map.delete(item.id);}}}><img className="img" src={item.url} alt="" /></li>))}</ul></>);
}
export default CompRef;

可以看出上面的确实现了效果,但是有个小Bug,大家可以去测试下,自己排查优化下。


修复代码

import { useEffect, useState, useRef } from "react";
import { flushSync } from "react-dom";
import "./compref.css";
function CompRef() {const [catLists, setCatLists] = useState([]);const [index, setIndex] = useState(0);const itemsRef = useRef(null);const nowIndex = useRef(0);useEffect(async () => {const getData = await fetch("https://xxxxxxxxxxxxxxxxxxxxxxx");const data = await getData.json();const lists = data.map((item, index) => ({ id: index, url: item.url }));console.log("🚀 ~ useEffect ~ data:", lists);setCatLists(lists);}, []);function getMap() {if (!itemsRef.current) {// 首次运行时初始化 Map。itemsRef.current = new Map();}return itemsRef.current;}function handleClick() {flushSync(() => {if (index < catLists.length - 1) {setIndex((index) => index + 1);nowIndex.current = index + 1;} else {setIndex(0);nowIndex.current = 0;}console.log(index);console.log("🚀 ~ CompRef ~ nowIndex:", nowIndex);});const map = getMap();const node = map.get(nowIndex.current);node.scrollIntoView({behavior: "smooth",block: "nearest",inline: "center",});}return (<><div>CompRef</div><button onClick={handleClick}>click</button><ul className="box">{catLists.map((item, i) => (<likey={item.id}className={index === i && "active"}ref={(node) => {const map = getMap();if (node) {map.set(item.id, node);} else {map.delete(item.id);}}}><img className="img" src={item.url} alt="" /></li>))}</ul></>);
}
export default CompRef;
  • 实现效果请添加图片描述
    这样,就不会延迟显示一张图片了

总结

react17中

1、在react可调度范围内的setState是异步的,并且多次setState会合并只执行最后一次,进行批量更新。

  • react合成事件
  • 生命周期
  • 事件处理,如onClickonChange等。

2、在react可调度范围外的setState是同步的。

  • 宏任务 setTimeoutsetInterval
  • 微任务 .then
  • 原生 js 绑定事件 document.addEventListener()

3、setState 并非真正的异步,而是通过设置全局变量 isBatchingUpdates 来判断 setState是先存进队列还是直接更新,如果值为true,则执行异步操作,如果为false,则直接更新。
isBatchingUpdates 会在 React 可以控制的地方,则为true,比如React生命周期和合成事件中,而在外部 react 无法控制的地方,比如原生事件,具体就是在 addEventListenersetTimeoutsetInterval.then等事件中,就只能同步。

react18

React18版本引入了自动批处理功能,批处理是指,当 React 在一个单独的渲染事件中批量处理多个状态更新以此实现优化性能。如果没有自动批处理的话,我们仅能够在 React 事件处理程序中批量更新。在 React 18 之前,默认情况下 promise、setTimeout、原生应用的事件处理程序以及任何其他事件中的更新都不会被批量处理;但现在,这些更新内容都会被自动批处理。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机专业大学四年的学习路线(非常详细),零基础入门到精通,看这一篇就够了

前言 许多学子选择踏上计算机这条充满挑战与机遇的道路。但在大学四年中&#xff0c;如何规划自己的学习路线&#xff0c;才能在毕业时脱颖而出&#xff0c;成为行业的佼佼者呢&#xff1f; 第一学年&#xff1a;基础知识的奠基 1.1 课程安排 在大学的第一年&#xff0c;重…

elementUI进度条el-progress不显示白色

效果图 通过设置百分比为100,动态修改进度条的宽度完成 <template><div class"myProgressBox"><div class"index">{{ index }}</div><div class"typeTitle">{{ typeTitle }}</div><div class"twoP…

【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第六篇-阶段总结篇】

因为马上就要进入下一个阶段&#xff0c;制作动态编辑体积纹理的模块。 但在这之前&#xff0c;要在这一章做最后一些整理。 首先&#xff0c;我们完成没完成的部分。其次&#xff0c;最后整理一下图表。最后&#xff0c;本文附上正在用的贴图 完善Shader 还记得我们之前注…

『完整代码』坐骑召唤

创建一个按钮 作为召唤/消失坐骑的开关 将预制体放入指定文件夹 命名为Mount01 创建脚本并编写&#xff1a;CallMount.cs using UnityEngine; using UnityEngine.UI; public class CallMount : MonoBehaviour{public Button callBtn;GameObject mountPrefab;GameObject mountIn…

嵌套div导致子区域margin失效问题解决

嵌套div导致子区域margin失效问题解决 现象原因解决方法 现象 <div class"prev"></div> <div class"parent"><div class"child"></div><div class"child"></div> </div> <div cl…

Netty无锁化设计之对象池实现

池化技术是比较常见的一种技术&#xff0c;在平时我们已经就接触很多了&#xff0c;比如线程池&#xff0c;数据库连接池等等。当我们要使用一个资源的时候从池中去获取&#xff0c;用完就放回池中以便其他线程可以使用&#xff0c;这样的目的就是为了减少资源开销&#xff0c;…

MySQL-23.多表查询-内连接

一.内连接 -- 多表查询 select * from tb_emp,tb_dept where tb_emp.dept_id tb_dept.id;-- 内连接 -- A.查询员工的姓名&#xff0c;及所属的部门名称&#xff08;隐式内连接实现&#xff09; select tb_emp.name as 员工姓名,tb_dept.name as 部门名称 from tb_emp,tb_dep…

简单介绍冯诺依曼体系

现代的计算机, 大多遵守冯诺依曼体系结构 CPU中央处理器&#xff1a;进行算术运算和逻辑判断。存储器&#xff1a;分为外存和内存&#xff0c;用于存储数据&#xff08;使用二进制方式存储&#xff09;。输入设备&#xff1a;用户给计算机发号施令。输出设备&#xff1a;计算机…

RISC-V笔记——Pipeline依赖

1. 前言 RISC-V的RVWMO模型主要包含了preserved program order、load value axiom、atomicity axiom、progress axiom和I/O Ordering。今天主要记录下preserved program order(保留程序顺序)中的Pipeline Dependencies(Pipeline依赖)。 2. Pipeline依赖 Pipeline依赖指的是&a…

LeetCode_2520. 统计能整除数字的位数_java

1、题目 2520. 统计能整除数字的位数https://leetcode.cn/problems/count-the-digits-that-divide-a-number/ 给你一个整数 num &#xff0c;返回 num 中能整除 num 的数位的数目。 如果满足 nums % val 0 &#xff0c;则认为整数 val 可以整除 nums 。 示例 1&#xff1a;…

TiDB替换Starrocks:业务综合宽表迁移的性能评估与降本增效决策

作者&#xff1a; 我是人间不清醒 原文来源&#xff1a; https://tidb.net/blog/6638f594 1、 场景 业务综合宽表是报表生成、大屏幕展示和数据计算处理的核心数据结构。目前&#xff0c;这些宽表存储在Starrocks系统中&#xff0c;但该系统存在显著的性能瓶颈。例如&#…

如何实现金蝶商品数据集成到电商系统的SKU

如何实现金蝶商品数据集成到电商SKU系统 金蝶商品数据集成到电商SKU的技术实现 在现代企业的数据管理中&#xff0c;系统间的数据对接与集成是提升业务效率和准确性的关键环节。本文将分享一个实际案例&#xff1a;如何通过轻易云数据集成平台&#xff0c;将金蝶云星辰V2中的商…

实战华为AC6508无线控制器+华为无线AP上线配置(AirEngine5762S-12+AirEngine5760-10)+无线WIFI配置

一、适用场景 1、适用于企业环境、校园环境、大户型家庭多层楼环境。 2、对于无线网络需要集中管理和监测的环境&#xff0c;无线wifi覆盖范围面积大&#xff0c;适用本实例。 3、当无线WIFI需要从一个区域到另一个区域无缝漫游时&#xff0c;确保应用不掉线&#xff0c;可使用…

简单有效修复d3d9.dll错误,11种d3d9.dll错误详细解决办法教程

当你遇到d3d9.dll文件丢失的问题时&#xff0c;可以通过今天的这篇文章详细的步骤来尝试修复这个问题&#xff0c;今天将教大家十一种d3d9.dll丢失修复的方法。 1. 重新安装DirectX以恢复d3d9.dll d3d9.dll是DirectX的一部分&#xff0c;因此重新安装DirectX通常可以解决d3d9.…

C#描述-计算机视觉OpenCV(7):MSER特征检测

C#描述-计算机视觉OpenCV&#xff08;7&#xff09;&#xff1a;MSER特征检测 基本概念操作实例效果优化 基本概念 前文C#描述-计算机视觉OpenCV&#xff08;6&#xff09;&#xff1a;形态学描述了如何对图像的前后景特征形态进行检测与运算&#xff0c;本篇将分析基于形态的…

Safari 中 filter: blur() 高斯模糊引发的性能问题及解决方案

目录 引言问题背景&#xff1a;filter: blur() 引发的问题产生问题的原因分析解决方案&#xff1a;开启硬件加速实际应用示例性能优化建议常见的调试工具与分析方法 引言 在前端开发中&#xff0c;CSS滤镜&#xff08;如filter: blur()&#xff09;的广泛使用为页面带来了各种…

大数据-173 Elasticsearch 索引操作 增删改查 详细 JSON 操作

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

后台管理员登录实现--系统篇

我的小系统后台原来就有一个上传图片的功能还夹带个删除图片的功能&#xff0c;还嵌到了一个菜单里面。之前效果如下 那么现在为了加大安全力度&#xff0c;想增加一个登录页面。通过登录再到这个页面。看着貌似很简单&#xff0c;但是听我细细说来&#xff0c;要新增些什么东西…

KMP 算法

目录 KMP 算法 算法思路 为什么不需要在主串中进行回退 计算 next 数组 代码实现 next 数组优化 查找所有起始位置 KMP 算法 KMP 算法是一种改进的字符串匹配算法&#xff0c;由 D.E.Knuth&#xff0c;J.H.Morris 和 V.R.Pratt 提出的&#xff0c;因此人们称它为 克努特…

(北京政务服务满意度公司)满意度调查助力服务质量提升

在当今社会&#xff0c;&#xff08;政务服务满意度公司&#xff09;政务窗口服务的质量直接关系到市民的日常生活和城市的健康发展。为了解市民对政务窗口服务的满意度&#xff0c;提升服务质量&#xff0c;某市委托民安智库专业市场调查公司开展了政务窗口服务满意度调查&…