refs创建 & 挂载
官方文档:https://react.docschina.org/docs/refs-and-the-dom.html
在React
单向数据流中,props
是父组件与子组件交互的唯一方式,要修改一个子组件,一般只能通过更新props
重新渲染。在某些情况下,需要在典型数据流之外强制修改子组件,被修改的子组件可能是一个React
组件实例,也可能是一个DOM
元素
ref
属性附加到React
元素上,以便访问。可以附加到以下几种节点:
- 使用
React.createRef()
方法创建一个ref
对象实例,附加到HTML
元素上,接收底层DOM
元素作为其current
属性 - 挂载到
class
组件上,其current
指向该类组件实例 - 不能挂载到函数组件上,因为函数组件没有实例
挂载到HTML
元素上比较常见,值得了解的是挂载在class
组件上
示例1:
import React from "react";
class CustomTextInput extends React.Component {
constructor (props) {
super(props)
this.textInputRef = React.createRef()
this.focusTextInput = this.focusTextInput.bind(this)
}
focusTextInput() {
this.textInputRef.current && this.textInputRef.current.focus()
}
render () {
return (
<>
<input ref={this.textInputRef} />
</>
)
}
}
export default class Home extends React.Component {
constructor (props) {
super(props)
this.inputRef = React.createRef()
}
componentDidMount() {
this.inputRef.current.focusTextInput()
}
render() {
return (
<>
<CustomTextInput ref={this.inputRef} />
</>
)
}
}
代码解释:
- 在
Home
组件中创建了一个inputRef
对象实例,它被附加在CustomTextInput
组件实例上,**inputRef.current
**指向该组件实例 CustomTextInput
中的内容,需要关注focusTextInput()
方法,它修改的内容是:input
输入框获取焦点- 当父级组件
componentDidMount
,使用inputRef.current
访问子组件,并调用子组件的方法,获取焦点
refs回调
不仅可以使用React.createRef()
方法创建ref
实例引用React
元素,还可以使用一个回调函数,绑定React
元素
示例2:
import React from "react";
class CustomTextInput extends React.Component {
render () {
return (
<>
<input ref={this.props.inputRef}/>
</>
)
}
}
export default class Home extends React.Component {
constructor (props) {
super(props)
this.inputRef = null
this.setInputRef = element => this.inputRef = element
this.focusTextInput = this.focusTextInput.bind(this)
}
focusTextInput() {
this.inputRef && this.inputRef.focus()
}
render() {
return (
<>
<CustomTextInput inputRef={this.setInputRef} />
<hr />
<button onClick={this.focusTextInput}>聚焦</button>
</>
)
}
}
代码解释:
- 将输入框子组件的一些逻辑全部都提升到父组件中控制,子组件差不多只用于展示了
- 在父组件中定义了
this.setInputRef = element => this.inputRef = element
函数,而且将该函数传递给CustomTextInput
的inputRef
属性 - 在
CustomTextInput
中又把父级的inputRef
传递给input
的ref
- 当点击【聚焦】按钮时,输入框成功聚焦
需要知道的只有一点,如果ref
属性接收的是一个函数,在组件挂载后,React
元素(组件或者HTML
元素)会作为refs
回调函数的第一个参数传递,因此this.inputRef
最终指向了CustomTextInput
组件内的input
元素
React 将在组件挂载时,会调用 ref 回调函数并传入 DOM 元素,当卸载时调用它并传入 null。在 componentDidMount 或 componentDidUpdate 触发前,React 会保证 refs 一定是最新的