1.Refs是什么
Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素。
2.如何使用Refs
1.字符串形式的ref(不推荐)
最方便的一种方式,但是不推荐,因为会有性能上的问题
class Demo extends React.Component {
alertInput1 = () => {
const { input1 } = this.refs;
alert(input1.value);
}
alertInput2 = () => {
const { input2 } = this.refs;
alert(input2.value);
}
render() {
return (
<div>
// 使用字符串形式的ref标记input元素,react会帮我们在渲染这个input元素时,将它存储在组件实例对象的refs属性中
<input ref="input1" type="text" placeholder="点击按钮显示输入内容" />
<button onClick={this.alertInput1} >点击显示左侧输入内容</button>
<input onBlur={this.alertInput2} ref="input2" type="text" placeholder="失去焦点显示输入内容" />
</div>
)
}
}
2.回调函数形式的ref
class Demo extends React.Component {
alertInput1 = () => {
const { input1 } = this;
alert(input1.value);
}
alertInput2 = () => {
const { input2 } = this;
alert(input2.value);
}
render() {
return (
<div>
// 使用回调函数的形式的ref,react会帮我们在渲染这个input元素时调用,调用时会传入一个参数,这个参数就是input元素
<input ref="e => this.input1 = e" type="text" placeholder="点击按钮显示输入内容" />
<button onClick={this.alertInput1} >点击显示左侧输入内容</button>
<input onBlur={this.alertInput2} ref="e => this.input2 = e" type="text" placeholder="失去焦点显示输入内容" />
</div>
)
}
}
React官网解释:如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素。这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。
class Demo extends React.Component {
state = { status: true }
updateStatus = () => {
cosnt { status } = this.state;
// 调用setState更改state内的值时,会触发重新渲染,即组件实例调用render方法
this.setState({ status: !status });
}
alertInput = () => {
const { input } = this;
alert(input.value);
}
saveInput = (e) => {
this.input = e;
console.log('input ref: ', e); // 更新渲染时不会被触发
}
render() {
return (
<div>
// 当触发更新渲染时 Output: input ref: null
// input ref: input
<input ref="(e) => { this.input = e; console.log('input ref: ', e) }" type="text" placeholder="点击按钮显示输入内容" />
// 如果使用如下class 的绑定函数方式,则可以避免上述问题
{/*<input ref="this.saveInput" type="text" placeholder="点击按钮显示输入内容" />*/}
<button onClick={this.alertInput1} >点击显示左侧输入内容</button>
<button onClick={this.updateStatus} >点击切换状态</button>
</div>
)
}
}
3.使用React.creatRef的ref
class Demo extends React.Component {
myRef1 = React.creatRef();
myRef2 = React.creatRef();
alertInput1 = () => {
alert(this.myRef1.current.value);
}
alertInput2 = () => {
alert(this.myRef2.current.value);
}
render() {
return (
<div>
// 使用creatRef形式的ref,react会帮我们在渲染这个input元素时创建一个容器,该容器只会存储这一个元素,并且存储在该容器的current属性中
<input ref={this.myRef1} type="text" placeholder="点击按钮显示输入内容" />
<button onClick={this.alertInput1} >点击显示左侧输入内容</button>
<input onBlur={this.alertInput2} ref={this.myRef2} type="text" placeholder="失去焦点显示输入内容" />
</div>
)
}
}
注意:请勿过度使用Refs
class Demo extends React.Component {
myRef1 = React.creatRef();
alertInput1 = () => {
alert(this.myRef1.current.value);
}
alertInput2 = (event) => {
alert(event.target.value);
}
render() {
return (
<div>
<input ref={this.myRef1} type="text" placeholder="点击按钮显示输入内容" />
<button onClick={this.alertInput1} >点击显示左侧输入内容</button>
// 当触发事件的元素和数据来源的元素是同一个时,可以使用原生的event.target获取元素
<input onBlur={this.alertInput2} ref={this.myRef2} type="text" placeholder="失去焦点显示输入内容" />
</div>
)
}
}