一、理解
Refs(引用)是 React 中用于访问组件中的 DOM 元素或其他 React 组件实例的一种机制。它们提供了一种途径,使你可以在React中直接操作和访问DOM元素,或者在React组件之间进行通信。
用途:
- 焦点的管理、文本的选择、媒体的播放;
- 强制触发动画;
- 继承三方 DOM 库;
二、创建refs的方式有哪些
2.1、字符串 Refs(不建议使用)
字符串 Refs 是 React 中的一种创建 Refs 的方式,但自 React 16.3 版本开始,官方不再推荐使用它,因为它存在一些潜在的问题,比如性能问题和可维护性问题。然而,为了完整性,我将展示如何使用字符串 Refs,但请谨慎使用它们。
在字符串 Refs 中,你可以将 Ref 分配为一个字符串,通常是在 componentDidMount
中进行分配,然后你可以通过访问 this.refs
来获取引用。
以下是一个示例:
import React, { Component } from 'react';
class MyComponent extends Component {
componentDidMount() {
// 分配Ref为字符串
this.refs.myRefElement.focus();
}
render() {
return (
<div>
<input ref="myRefElement" /> {/* 分配Ref为字符串 */}
</div>
);
}
}
export default MyComponent;
在上面的示例中,我们使用字符串 "myRefElement"
分配 Ref 给 input
元素,然后在 componentDidMount
中通过 this.refs.myRefElement
访问该元素并将焦点聚焦到它。
尽管字符串 Refs 在过去是有效的,但它们已不再被官方推荐,因为它们在以下方面存在问题:
-
性能问题:字符串 Refs 在React内部需要维护一个额外的映射表,以便通过字符串名字查找Ref。这会导致性能问题,尤其在具有大量Refs的组件中。
-
可维护性:使用字符串 Refs 时,很难进行静态分析和检查,因此容易出现拼写错误或无法找到的Refs。
因此,建议在现代React应用程序中使用 React.createRef()
或 useRef
钩子来创建Refs,以提高性能和可维护性。
2.2、回调 Refs
回调 Refs 是一种在 React 组件中创建 Refs 的方式,它可以用于访问 DOM 元素或其他组件实例。这种方式在 React 16.3 之前是主要的 Refs 创建方式,虽然在 React 16.3 之后,官方推荐使用 React.createRef()
或 useRef
钩子来创建 Refs,但回调 Refs 仍然是一种有效的方法。
下面是如何使用回调 Refs 的详细描述:
-
创建 Refs:在组件中,首先定义一个变量来保存 Ref 对象,通常在构造函数中初始化为
null
。class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = null; } }
-
分配 Refs 到元素或组件:在需要引用的 DOM 元素或组件上,使用
ref
属性,将 Ref 变量设置为回调函数。setMyRef = (element) => { this.myRef = element; } render() { return ( <div> <input ref={this.setMyRef} /> </div> ); }
通过这个回调函数,
this.myRef
将会引用与之关联的 DOM 元素或组件实例。 -
访问 Refs:在需要访问 Refs 的地方,可以使用
this.myRef
来获取引用的元素或组件。componentDidMount() { if (this.myRef) { this.myRef.focus(); // 通过 Ref 聚焦到输入框 } }
回调 Refs 的优点是它们在更早的 React 版本中是有效的,并且能够很好地用于访问 DOM 元素或子组件的实例。然而,随着 React 版本的更新,官方更推荐使用 React.createRef()
或 useRef
钩子,因为它们在性能和可维护性方面更有优势。当需要在现代 React 项目中创建 Refs 时,通常更好的选择是使用 React.createRef()
(类组件)或 useRef
钩子(函数式组件)。
2.3、React.createRef()(推荐使用)
在 React 16.3 以及之后的版本中,你可以使用内置的 React.createRef() 方法来创建 Refs。这是一种官方推荐的方式。
使用 React.createRef()
方式创建 Refs 很简单。以下是一个具体的示例:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef(); // 创建Ref对象
}
componentDidMount() {
// 在组件渲染后,可以访问DOM元素
this.myRef.current.focus(); // 聚焦到DOM元素
}
render() {
return (
<div>
<input ref={this.myRef} /> {/* 将Ref分配给input元素 */}
<button onClick={this.focusInput}>Focus Input</button>
</div>
);
}
focusInput = () => {
// 在事件处理程序中访问Ref
this.myRef.current.focus();
};
}
export default MyComponent;
在上面的示例中,我们首先在构造函数中使用 React.createRef()
创建了一个Ref对象,然后在input
元素上使用 ref
属性将这个Ref分配给DOM元素。在componentDidMount
生命周期方法中,我们使用 this.myRef.current
来访问DOM元素并将焦点聚焦到input
上。我们还在一个按钮的点击事件处理程序中使用Ref,再次将焦点聚焦到input
上。
这就是使用 React.createRef()
创建和访问Refs的一般过程。这种方式通常用于访问和操作DOM元素,或者引用子组件的实例。
2.4、通过 React Hook(函数式组件)
使用 React Hook(useRef
钩子)在函数式组件中创建 Refs同样非常简单。以下是一个具体的示例:
import React, { useRef, useEffect } from 'react';
function MyComponent() {
const myRef = useRef(null); // 创建Ref对象
useEffect(() => {
// 在组件渲染后,可以访问DOM元素
myRef.current.focus(); // 聚焦到DOM元素
}, []);
const focusInput = () => {
// 在事件处理程序中访问Ref
myRef.current.focus();
};
return (
<div>
<input ref={myRef} /> {/* 将Ref分配给input元素 */}
<button onClick={focusInput}>Focus Input</button>
</div>
);
}
export default MyComponent;
在上面的示例中,我们首先使用 useRef(null)
创建一个Ref对象。useRef()
的参数是初始值,通常设置为 null
,因为它在初始渲染时并不关心实际的值。
然后,我们使用 useEffect
钩子来模拟 componentDidMount
生命周期方法,在其中使用 myRef.current
访问DOM元素并将焦点聚焦到input
上。useEffect
接受第二个参数,一个依赖数组,这里为空数组,表示只在组件的初始渲染时执行这个效果。
最后,我们在一个按钮的点击事件处理程序中再次使用Ref,将焦点聚焦到input
上。
使用 useRef
钩子可以在函数式组件中方便地创建和访问Refs,以及执行与Refs相关的操作,而无需使用类组件。这种方式在React 16.8及之后的版本中可用。
三、例
3.1、焦点管理
以下是一个简单的 React 示例,演示如何使用 Refs 来管理焦点,具体是将焦点从一个输入框移动到另一个输入框。这个示例包括一个按钮,当点击按钮时,将焦点从一个输入框转移到另一个输入框。
import React, { Component } from 'react';
class FocusManagementExample extends Component {
constructor(props) {
super(props);
this.inputRef1 = React.createRef(); // 创建 Ref for Input 1
this.inputRef2 = React.createRef(); // 创建 Ref for Input 2
}
moveFocus = () => {
this.inputRef2.current.focus(); // 移动焦点到 Input 2
};
render() {
return (
<div>
<input ref={this.inputRef1} placeholder="Input 1" />
<input ref={this.inputRef2} placeholder="Input 2" />
<button onClick={this.moveFocus}>Move Focus to Input 2</button>
</div>
);
}
}
export default FocusManagementExample;
在这个示例中,我们首先创建两个 Refs,this.inputRef1
和 this.inputRef2
,分别引用两个输入框。然后,在 moveFocus
方法中,我们使用 this.inputRef2.current.focus()
来将焦点移动到第二个输入框。当点击按钮时,调用 moveFocus
方法,焦点将从输入框 1 移动到输入框 2。
3.2、文本的选择
下面是一个简单的 React 示例,演示如何使用 Refs 来实现文本选择的功能。在这个示例中,有一个文本输入框和一个按钮,点击按钮后会选择文本输入框中的文本。
import React, { Component } from 'react';
class TextSelectionExample extends Component {
constructor(props) {
super(props);
this.inputRef = React.createRef(); // 创建 Ref for the text input
}
selectText = () => {
if (this.inputRef.current) {
this.inputRef.current.select(); // 选择文本输入框中的文本
}
};
render() {
return (
<div>
<input ref={this.inputRef} placeholder="Type some text" />
<button onClick={this.selectText}>Select Text</button>
</div>
);
}
}
export default TextSelectionExample;
在这个示例中,我们首先创建一个 Ref this.inputRef
并将其分配给输入框。然后,我们定义了 selectText
方法,该方法使用 this.inputRef.current.select()
来选择文本输入框中的文本。当按钮被点击时,调用 selectText
方法,文本输入框的文本将被选中。
3.3、媒体的播放
以下是一个使用 React 来创建一个简单的媒体播放器的示例。这示例包括一个播放/暂停按钮、一个音频元素,以及一些状态管理来控制播放状态。
import React, { Component } from 'react';
class MediaPlayerExample extends Component {
constructor(props) {
super(props);
this.audioRef = React.createRef(); // 创建 Ref for the audio element
this.state = {
isPlaying: false,
};
}
togglePlay = () => {
const audio = this.audioRef.current;
if (this.state.isPlaying) {
audio.pause();
} else {
audio.play();
}
this.setState({ isPlaying: !this.state.isPlaying });
};
render() {
return (
<div>
<audio ref={this.audioRef} controls>
<source src="your-audio-file.mp3" type="audio/mpeg" />
Your browser does not support the audio element.
</audio>
<button onClick={this.togglePlay}>
{this.state.isPlaying ? 'Pause' : 'Play'}
</button>
</div>
);
}
}
export default MediaPlayerExample;
在这个示例中,我们首先创建一个 Ref this.audioRef
并将其分配给audio
元素。然后,我们定义了 togglePlay
方法,该方法会根据当前播放状态(isPlaying
)来播放或暂停音频,然后更新状态以反映新的播放状态。
<audio>
元素用于播放音频文件,并带有控件来控制播放。你可以在 <source>
元素的 src
属性中指定音频文件的URL。
按钮元素允许用户点击来切换播放/暂停状态,并在按钮上显示当前状态。
这是一个简单的媒体播放器示例,你可以根据实际需求扩展它以添加更多功能,例如音量控制、跳过、循环等功能。
3.4、强制触发动画
在 React 中,你可以使用 ref
来访问组件或 DOM 元素,以便在需要时强制触发动画。以下是一个简单的示例,演示如何使用 React 和 ref
来强制触发 CSS 动画:
import React, { Component } from 'react';
class AnimationExample extends Component {
constructor(props) {
super(props);
this.animationBoxRef = React.createRef(); // 创建 Ref for the animated box
}
startAnimation = () => {
const box = this.animationBoxRef.current;
// 添加 CSS 类以触发动画
box.classList.add('animate');
// 在动画完成后,移除 CSS 类以重置动画
box.addEventListener('animationend', () => {
box.classList.remove('animate');
});
};
render() {
return (
<div>
<div
ref={this.animationBoxRef}
className="box"
></div>
<button onClick={this.startAnimation}>Start Animation</button>
</div>
);
}
}
export default AnimationExample;
在这个示例中,我们首先创建了一个 Ref this.animationBoxRef
并将其分配给一个 div
元素,该 div
元素表示动画的目标。然后,我们定义了 startAnimation
方法,该方法使用 classList
添加一个 CSS 类 animate
到 div
元素上,以触发动画。
在动画结束后,我们使用 addEventListener
监听 animationend
事件,并在事件处理程序中移除 CSS 类 animate
以重置动画状态。
按钮元素允许用户点击来触发动画。你可以在 CSS 中定义相应的动画效果,例如通过 @keyframes
规则来定义动画的细节。
3.5、继承三方 DOM 库
继承第三方 DOM 库通常需要在 React 中使用 ref
来访问和操作第三方库中的 DOM 元素。以下是一个示例,演示如何在 React 中继承第三方 DOM 库(这里以使用D3.js库为例):
首先,确保你的项目中已经引入了 D3.js 库,你可以使用 npm 或通过 <script>
标签将其添加到你的项目中。
import React, { Component } from 'react';
import * as d3 from 'd3'; // 引入 D3.js
class D3IntegrationExample extends Component {
constructor(props) {
super(props);
this.svgRef = React.createRef(); // 创建 Ref for the SVG element
}
componentDidMount() {
// 在组件挂载后,初始化 D3.js 操作
const svg = d3.select(this.svgRef.current);
// 在 SVG 中添加一个矩形
svg
.append('rect')
.attr('x', 10)
.attr('y', 10)
.attr('width', 100)
.attr('height', 50)
.style('fill', 'blue');
}
render() {
return (
<div>
<svg ref={this.svgRef} width={200} height={100}></svg>
</div>
);
}
}
export default D3IntegrationExample;
在这个示例中,我们首先引入了 D3.js 库。然后,我们创建一个 Ref this.svgRef
并将其分配给一个 <svg>
元素,这个元素将用来绘制 D3.js 图形。
在 componentDidMount
生命周期方法中,我们使用 D3.js 的 d3.select
方法选择了这个 <svg>
元素,并在其中添加一个蓝色矩形。你可以根据 D3.js 的文档和需要来进行更复杂的操作。
这个示例演示了如何在 React 中继承第三方 DOM 库,特别是 D3.js。你可以根据你的项目需求,继承其他的第三方库,然后使用 ref
来访问和操作其 DOM 元素。
参考地址
chatgpt文章来源:https://www.toymoban.com/news/detail-735780.html
https://zhuanlan.zhihu.com/p/549934728文章来源地址https://www.toymoban.com/news/detail-735780.html
到了这里,关于React 组件的3大属性: refs的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!