ref:组件中的标签可以通过定义ref属性来标识自己
14.1 字符串形式的ref
代码 App.jsx
import React from "react";
class App extends React.Component {
// 字符串形式的ref尽量不用,已经弃用,有效率问题
// 字符串形式的ref尽量不用,已经弃用,有效率问题
// 字符串形式的ref尽量不用,已经弃用,有效率问题
popClick = () => {
// console.log(document.getElementsByTagName("input")[0].value);
const {inputRef} = this.refs;
alert(inputRef.value)
}
render() {
return (
<>
<input type="text" placeholder="请输入内容" ref={"inputRef"}/>
<button onClick={this.popClick}>点击获取input内容</button>
</>
)
}
}
export default App
存在效率的问题,已经被弃用
14.2 回调形式的ref (推荐)
何时使用Refs?
管理焦点,文本选择或媒体播放
触发强制动画
集成第三方DOM库
避免使用refs来做任何可以通过声明式实现来完成的事情,不要过度使用refs。
如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素。这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。
14.2.1 (推荐)* 增加点击事件,验证内联方式定义的ref在组件更新的时候会执行两次
代码
import React from "react";
class App extends React.Component {
state = {jack: true};
// 回调形式的ref
popClick = () => {
// console.log(document.getElementsByTagName("input")[0].value);
// const {inputRef} = this.refs;
alert(this.inputRef.value)
}
// 增加点击事件,验证内联方式定义的ref在组件更新的时候会执行两次
handleClick = () => {
this.setState({jack: !this.state.jack})
}
// 此处 refs是通过内联函数方式定义的
render() {
return (
<>
<input type="text" placeholder="请输入内容" ref={(e) => (this.inputRef = e, console.log("ref执行了"))}/>
<button onClick={this.popClick}>点击获取input内容</button>
<button onClick={this.handleClick}>点击更新组件</button>
</>
)
}
}
export default App
运行结果(点击两次更新组件按钮)
14.2.2 将ref不内联,抽离出来(最常用)* class
将ref定义成class的绑定函数,不会因为更新组件带来重新执行的问题
代码
import React from "react";
class App extends React.Component {
state = {jack: true};
// 回调形式的ref
popClick = () => {
// console.log(document.getElementsByTagName("input")[0].value);
// const {inputRef} = this.refs;
alert(this.inputRef.value)
}
// 增加点击事件,验证内联方式定义的ref在组件更新的时候会执行两次
handleClick = () => {
this.setState({jack: !this.state.jack})
}
// 将ref定义成class的绑定函数,不会因为更新组件带来重新执行的问题
refFun = (e) => (this.inputRef = e, console.log("ref执行了"));
// 此处 refs是通过内联函数方式定义的
render() {
return (
<>
<input type="text" placeholder="请输入内容" ref={this.refFun}/>
<button onClick={this.popClick}>点击获取input内容</button>
<button onClick={this.handleClick}>点击更新组件</button>
</>
)
}
}
export default App
按更新组件按钮三次,结果(首次进入页面,ref执行一次正常)
14.3 createRef创建ref
-
createRef
- Refs 是使用
React.createRef()
创建的,并通过ref
属性附加到 React 元素。在构造组件时,通常将 Refs 分配给实例属性,以便可以在整个组件中引用它们 React.createRef()
调用后可以想象成创建了一个容器,这个容器可以储存被ref标识的元素节点- 创建了一个容器只能绑定一个节点,绑定多个节点会被覆盖
- Refs 是使用
代码
import React from "react";
class App extends React.Component {
// 一个容器只能绑定一个节点
inputRef1 = React.createRef();
inputRef2 = React.createRef();
popClick = () => {
// console.log(this.inputRef.current.value);
alert(this.inputRef1.current.value)
alert(this.inputRef2.current.value)
}
// 此处 refs是通过内联函数方式定义的
render() {
return (
<>
<input type="text" placeholder="请输入内容" ref={this.inputRef1}/>
<input type="text" placeholder="请输入内容" ref={this.inputRef2}/>
<button onClick={this.popClick}>点击获取input内容</button>
</>
)
}
}
export default App
- 不要过度使用ref
当获取input内容和按钮分开时,就需要用ref,但是没有button的话,可以直接使用失焦方法调用
import React from "react";
class App extends React.Component {
// 一个容器只能绑定一个节点
inputRef1 = React.createRef();
inputRef2 = React.createRef();
popClick = () => {
// console.log(this.inputRef.current.value);
alert(this.inputRef1.current.value)
alert(this.inputRef2.current.value)
}
// input 失焦事件触发 可以替代ref
// input 失焦事件触发 可以替代ref
// input 失焦事件触发 可以替代ref
// input 失焦事件触发 可以替代ref
blur = (e) => {
console.log(e.target.value);
}
// 此处 refs是通过内联函数方式定义的
render() {
return (
<>
<input type="text" placeholder="请输入内容" ref={this.inputRef1}/>
<input type="text" placeholder="请输入内容" ref={this.inputRef2}/>
<button onClick={this.popClick}>点击获取input内容</button>
<input type="text" onBlur={this.blur}/>
</>
)
}
}
export default App