react 学习 —— 16、使用 ref 操作 DOM

什么时候使用 ref 操作 DOM?

有时你可能需要访问由 React 管理的 DOM 元素 —— 例如,让一个节点获得焦点、滚动到它或测量它的尺寸和位置。在 React 中没有内置的方法来做这些事情,所以你需要一个指向 DOM 节点的 ref 来实现。

怎么使用 ref 操作 DOM?

首先,引入 useRef Hook:

import { useRef } from 'react';

然后,在你的组件中使用它声明一个 ref:

const myRef = useRef(null);

最后,将你的 ref 作为 ref 属性传递给你想要获得 DOM 节点的 JSX 标签:

<div ref={myRef}>

useRef Hook 返回一个对象,该对象有一个名为 current 的属性。最初,myRef.current 是 null。当 React 为这个 <div /> 创建一个 DOM 节点时,React 会把对该节点的引用放入 myRef.current。然后,你可以从 事件处理器 访问此 DOM 节点,并使用在其上定义的内置浏览器 API。

myRef.current.scrollIntoView();

如何使用 ref 回调管理 ref 列表?

有时候,你可能需要为列表中的每一项都绑定 ref ,而你又不知道会有多少项。像下面这样做是行不通的:

<ul>{items.map((item) => {// 行不通!const ref = useRef(null);return <li ref={ref} />;})}
</ul>

这是因为 Hook 只能在组件的顶层被调用。不能在循环语句、条件语句或 map() 函数中调用 useRef 。
一种可能的解决方案是用一个 ref 引用其父元素,然后用 DOM 操作方法如 querySelectorAll 来寻找它的子节点。然而,这种方法很脆弱,如果 DOM 结构发生变化,可能会失效或报错。
另一种解决方案是将函数传递给 ref 属性。这称为 ref 回调。当需要设置 ref 时,React 将传入 DOM 节点来调用你的 ref 回调,并在需要清除它时传入 null 。这使你可以维护自己的数组或 Map,并通过其索引或某种类型的 ID 访问任何 ref。

import { useRef } from 'react';export default function CatFriends() {const itemsRef = useRef(null);function scrollToId(itemId) {const map = getMap();const node = map.get(itemId);node.scrollIntoView({behavior: 'smooth',block: 'nearest',inline: 'center'});}function getMap() {if (!itemsRef.current) {// 首次运行时初始化 Map。itemsRef.current = new Map();}return itemsRef.current;}return (<><nav><button onClick={() => scrollToId(0)}>Tom</button><button onClick={() => scrollToId(5)}>Maru</button><button onClick={() => scrollToId(9)}>Jellylorum</button></nav><div><ul>{catList.map(cat => (<likey={cat.id}ref={(node) => {const map = getMap();if (node) {map.set(cat.id, node);} else {map.delete(cat.id);}}}><imgsrc={cat.imageUrl}alt={'Cat #' + cat.id}/></li>))}</ul></div></>);
}const catList = [];
for (let i = 0; i < 10; i++) {catList.push({id: i,imageUrl: 'https://placekitten.com/250/200?image=' + i});
}

怎样访问另一个组件的 DOM 节点?

当你将 ref 放在像 这样输出浏览器元素的内置组件上时,React 会将该 ref 的 current 属性设置为相应的 DOM 节点(例如浏览器中实际的 )。
但是,如果你尝试将 ref 放在 你自己的 组件上,例如 ,默认情况下你会得到 null。

import { useRef } from 'react';function MyInput(props) {return <input {...props} />;
}export default function MyForm() {const inputRef = useRef(null);function handleClick() {inputRef.current.focus();}return (<><MyInput ref={inputRef} /><button onClick={handleClick}>聚焦输入框</button></>);
}

为了帮助您注意到这个问题,React 还会向控制台打印一条错误消息:
在这里插入图片描述
发生这种情况是因为默认情况下,React 不允许组件访问其他组件的 DOM 节点。甚至自己的子组件也不行!这是故意的。Refs 是一个应急方案,应该谨慎使用。手动操作 另一个 组件的 DOM 节点会使你的代码更加脆弱。

相反,想要 暴露其 DOM 节点的组件必须选择该行为。一个组件可以指定将它的 ref “转发”给一个子组件。下面是 MyInput 如何使用 forwardRef API:

import { forwardRef, useRef } from 'react';const MyInput = forwardRef((props, ref) => {return <input {...props} ref={ref} />;
});export default function Form() {const inputRef = useRef(null);function handleClick() {inputRef.current.focus();}return (<><MyInput ref={inputRef} /><button onClick={handleClick}>聚焦输入框</button></>);
}

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

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

相关文章

vue3里面vant组件的标签页使用?

一、绑一个v-model事件 二、让activeName的初始为0也就是默认是显示第一个标签页的下标 三、给标签页下面的东西进行一个判断 想让哪个优先显示就把哪个判断作为初始值存入

【逆向】Base64编码解码及逆向识别

示例代码 注意&#xff1a;该示例代码仅为Base64编码实现的其中一种&#xff0c;实际分析样本的Base64编码实现并不一定与此代码相同&#xff0c;读者应重点理解其原理部分&#xff0c;而忽略其实现形式的不同。 View Code 逆向识别 1、编码识别 2、解码识别 总结 1、识别代…

使用AI编写测试用例——详细教程

随着今年chatGPT的大热&#xff0c;每个行业都试图从这项新技术当中获得一些收益我之前也写过一篇测试领域在AI技术中的探索&#xff1a;软件测试中的AI——运用AI编写测试用例现阶段AI还不能完全替代人工测试用例编写&#xff0c;但是如果把AI当做一个提高效率的工具&#xff…

微信小程序之个人中心授权登录

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 1.了解微信授权登录 微信登录官网&#xff1a; 小程序登录https://developers.weixin.qq.com/miniprogram/d…

2023Jenkins连接k8s

首先配置k8s config文件 1.方式获取k8s密钥 cat .kube/config 2.导出方式或者密钥 kubectl config view --raw > k8s-config-admin pipeline {agent {kubernetes {yaml apiVersion: v1kind: Podmetadata:labels:some-label: devopsspec:containers:- name: dockerimage: d…

【广州华锐互动】建筑安全事故VR沉浸式体验系统

在建筑行业中&#xff0c;安全永远是首要的考虑因素。传统的安全培训方法&#xff0c;如书本教学、现场演示等&#xff0c;虽然能在一定程度上提高员工的安全意识&#xff0c;但这些方法往往缺乏实际体验&#xff0c;员工在真正面临危险时可能无法做出正确的判断和反应。近年来…

【Axure高保真原型】可视化图表图标

今天和粉丝们免费分享可视化图表图标原型模板&#xff0c;包括柱状图、条形图、环形图、散点图、水波图等常用的可视化图表图标。 【原型效果】 【原型预览】 https://axhub.im/ax9/d402c647c82f9185/#c1 【原型下载】 这个模板可以在 Axure高保真原型哦 小程序里免费下载哦…

自然语言处理---Transformer机制详解之Self attention机制详解

1 Self-attention的特点 self-attention是一种通过自身和自身进行关联的attention机制, 从而得到更好的representation来表达自身. self-attention是attention机制的一种特殊情况&#xff0c;在self-attention中, QKV, 序列中的每个单词(token)都和该序列中的其他所有单词(to…

STM32cubemx对FreeRTOS的适配(工程模板配置)

文章目录 前言一、工程的创建二、什么是CMSIS三、STM32cubemx生成的FreeRTOS工程分析总结 前言 本篇文章将带大家使用STM32cubemx对FreeRTOS进行工程模板的配置。 一、工程的创建 1.开始工程的创建&#xff1a; 2.芯片型号选择&#xff1a; 3.修改时钟为TIM8&#xff1a; …

阶段七-Day01-Spring01

一、Spring框架介绍 1. 介绍 Spring Framework是由Spring团队研发的模块化、轻量级开源框架。其主要目的是为了简化项目开发。 Spring Framework前身是interface21&#xff0c;由Rod Johnson于2002年研发&#xff0c;主要是为了不使用EJB下依然能够构建高质量Java EE项目。E…

6.(vue3.x+vite)路由传参query与params区别

前端技术社区总目录(订阅之前请先查看该博客) 效果截图 一:路由传参有两种方式:params与query params与query区别 1:param,路由带“/”,query带“?” 2:query传过来的参数会显示到地址栏中 而params传过来的参数可以显示参数或隐藏参数到地址栏中(vue-router 4.1.4不…

IK分词器如何修改支持跨版本ES

一、问题描述&#xff1a;IK分词器版本和ES版本不一致&#xff0c;无法找到和自己ES版本匹配的分词器。 IK分词器&#xff0c;提供的插件版本&#xff0c;远赶不上ES的更新版本&#xff0c;在使用过程中&#xff0c;不一定能顺利的找到与自己使用的ES版本相对应。在ES集群中使用…

【网络安全 --- xss-labs靶场通关(1-10关)】详细的xss-labs靶场通关思路及技巧讲解,让你对xss漏洞的理解更深刻

靶场安装&#xff1a; 靶场安装请参考以下博客&#xff0c;既详细有提供工具&#xff1a; 【网络安全 --- xss-labs靶场】xss-labs靶场安装详细教程&#xff0c;让你巩固对xss漏洞的理解及绕过技巧和方法&#xff08;提供资源&#xff09;-CSDN博客【网络安全 --- xss-labs通…

物证管理系统|智物证DW-S404是一套成熟系统

系统背景 我司物证智能管理系统&#xff08;智物证DW-S404&#xff09;是一套成熟系统&#xff0c;依托互3D技术、RFID技术、数据库技术、AI、视频分析技术对物证进行统一管理、分析的信息化、智能化、规范化的系统。 物证是公安或者监狱处理案件的关键凭证&#xff0c;针对过…

人工智能(5):深度学习简介

1 深度学习 —— 神经网络简介 深度学习&#xff08;Deep Learning&#xff09;&#xff08;也称为深度结构学习【Deep Structured Learning】、层次学习【Hierarchical Learning】或者是深度机器学习【Deep Machine Learning】&#xff09;是一类算法集合&#xff0c;是机器学…

【CSS】使用 CSS 实现一个宽高自适应的正方形

1. 利用 padding 或 vw <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><metaname"viewport"content"widthdevice-width, initial-scale1.0"><title>Document</title><st…

Java File与IO流学习笔记

内存中存放的都是临时数据&#xff0c;但是在断电或者程序终止时都会丢失 而硬盘则可以长久存储数据&#xff0c;即使断电&#xff0c;程序终止&#xff0c;也不会丢失 File File是java.io.包下的类&#xff0c;File类的对象&#xff0c;用于代表当前操作系统的文件(可以是文…

智慧公厕蜕变多功能城市智慧驿站公厕的创新

随着城市发展的不断推进&#xff0c;对公共设施的便利性和智能化要求也日益提高。为满足市民对高品质、便捷、舒适的公共厕所的需求&#xff0c;智慧公厕行业的领航厂家广州中期科技有限公司&#xff0c;全新推出了一体化智慧公厕驿站。凭借着“高科技碳中和物联网创意设计新经…

【Java基础面试四十二】、 static修饰的类能不能被继承?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a; static修饰的类能不能被…

设计模式-责任链设计模式

核心思想 客户端发出一个请求&#xff0c;链上的对象都有机会来处理这一请求&#xff0c;而客户端不需要知道谁是具体的处理对象让多个对象都有机会处理请求&#xff0c;避免请求的发送者和接收者之间的耦合关系&#xff0c;将这个对象连成一条调用链&#xff0c;并沿着这条链…