Refs 使用场景
在某些情况下,我们需要在典型数据流之外强制修改子组件,被修改的子组件可能是一个 React 组件的实例,也可能是一个 DOM 元素,例如:
管理焦点,文本选择或媒体播放。
触发强制动画。
集成第三方 DOM 库。
设置 Refs
1. createRef
支持在函数组件和类组件内部使用
createRef 是 React16.3 版本中引入的。
创建 Refs
使用 React.createRef() 创建 Refs,并通过 ref 属性附加至 React 元素上。通常在构造函数中,将 Refs 分配给实例属性,以便在整个组件中引用。
访问 Refs
当 ref 被传递给 render 中的元素时,对该节点的引用可以在 ref 的 current 属性中访问。
import React from 'react';
export default class MyInput extends React.Component {
constructor(props) {
super(props);
//分配给实例属性
this.inputRef = React.createRef(null);
}
componentDidMount() {
//通过 this.inputRef.current 获取对该节点的引用
this.inputRef && this.inputRef.current.focus();
}
render() {
//把 <input> ref 关联到构造函数中创建的 ——inputRef—— 上
return (
<input type="text" ref={this.inputRef}/>
)
}
}
ref 的值根据节点的类型而有所不同:
当 ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性。
当 ref 属性用于自定义的 class 组件时, ref 对象接收组件的挂载实例作为其 current 属性。
不能在函数组件上使用 ——ref—— 属性,因为函数组件没有实例。
总结:为 DOM 添加 ref,那么我们就可以通过 ref 获取到对该DOM节点的引用。而给React组件添加 ref,那么我们可以通过 ref 获取到该组件的实例【不能在函数组件上使用 ref 属性,因为函数组件没有实例】。
2. useRef
仅限于在函数组件内使用
useRef 是 React16.8 中引入的,只能在函数组件中使用。
创建 Refs
使用 React.useRef() 创建 Refs,并通过 ref 属性附加至 React 元素上。
const refContainer = useRef(initialValue);
useRef 返回的 ref 对象在组件的整个生命周期内保持不变。
访问 Refs
当 ref 被传递给 React 元素时,对该节点的引用可以在 ref 的 current 属性中访问。
import React from 'react';
export default function MyInput(props) {
const inputRef = React.useRef(null);
React.useEffect(() => {
inputRef.current.focus();
});
return (
<input type="text" ref={inputRef} />
)
}
关于 React.useRef() 返回的 ref 对象在组件的整个生命周期内保持不变,我们来和 React.createRef() 来做一个对比,代码如下:
import React, { useRef, useEffect, createRef, useState } from 'react';
function MyInput() {
let [count, setCount] = useState(0);
const myRef = createRef(null);
const inputRef = useRef(null);
//仅执行一次
useEffect(() => {
inputRef.current.focus();
window.myRef = myRef;
window.inputRef = inputRef;
}, []);
useEffect(() => {
//除了第一次为true, 其它每次都是 false 【createRef】
console.log('myRef === window.myRef', myRef === window.myRef);
//始终为true 【useRef】
console.log('inputRef === window.inputRef', inputRef === window.inputRef);
})
return (
<>
<input type="text" ref={inputRef}/>
<button onClick={() => setCount(count+1)}>{count}</button>
</>
)
}
3. 回调 Refs
支持在函数组件和类组件内部使用
React 支持 回调 refs 的方式设置 Refs。这种方式可以帮助我们更精细的控制何时 Refs 被设置和解除。
使用 回调 refs 需要将回调函数传递给 React元素 的 ref 属性。这个函数接受 React 组件实例 或 HTML DOM 元素作为参数,将其挂载到实例属性上,如下所示:
import React from 'react';
export default class MyInput extends React.Component {
constructor(props) {
super(props);
this.inputRef = null;
this.setTextInputRef = (ele) => {
this.inputRef = ele;
}
}
componentDidMount() {
this.inputRef && this.inputRef.focus();
}
render() {
return (
<input type="text" ref={this.setTextInputRef}/>
)
}
}
React 会在组件挂载时,调用 ref 回调函数并传入 DOM元素(或React实例),当卸载时调用它并传入 null。在 componentDidMount 或 componentDidUpdate 触发前,React 会保证 Refs 一定是最新的。
如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h63760.shtml