在 react 中,可以使用 refs 来访问 dom,或者在 render 中创建 react 对象。
使用 refs 的主要用途是
- 做一些动画的交互
- 媒体控件的播放
- 获取焦点、获取文本等
使用 refs 的方式有两种,一种是使用
React.createRef() API
,另一种是使用回调形式的 refs
。先来介绍第一种方式,使用
React.createRef() API
import React, {Component} from 'react'
export default class App extends React.Component {constructor(props) {super(props);
// 创建一个 ref 来存储 textInput 的 DOM 元素
this.textInput = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
// 直接使用原生 API 使 text 输入框获得焦点
// 注意:我们通过 "current" 来访问 DOM 节点
this.textInput.current.focus();
console.log(this.textInput.current);// 这边输出 input 的 dom 对象
}
render() {
// 告诉 React 我们想把 <input> ref 关联到
// 构造器里创建的 `textInput` 上
return (
<div>
<input
type="text"
ref={this.textInput} />
<input
type="button"
value="点击我获取焦点"
onClick={this.focusTextInput}
/>
</div>
);
}
}
第二种是
回调 Refs
,React 将在组件挂载时,会调用 ref 回调函数并传入 DOM 元素,当卸载时调用它并传入 null。在 componentDidMount 或 componentDidUpdate 触发前,React 会保证 refs 一定是最新的。
import React, {Component} from 'react'
export default class App extends React.Component {constructor(props) {super(props);
// 创建一个 ref 来存储 textInput 的 DOM 元素
this.textInput = null;
this.setTextInputRef = element => {this.textInput = element;};
this.focusTextInput = () => {
// 使用原生 DOM API 使 text 输入框获得焦点
if (this.textInput) this.textInput.focus();};
}
componentDidMount() {
// 组件挂载后,让文本框自动获得焦点
this.focusTextInput();}
render() {
// 使用 `ref` 的回调函数将 text 输入框 DOM 节点的引用存储到 React
// 实例上(比如 this.textInput)return (
<div>
<input
type="text"
ref={this.setTextInputRef}
/>
<input
type="button"
value="点击我获取焦点"
onClick={this.focusTextInput}
/>
</div>
);
}
}
后面来讲下,父子组件怎么样传递 refs,你可以在组件间传递回调形式的 refs,代码如下
import React, {Component} from 'react'
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class App extends React.Component {constructor(props) {super(props);
// 创建一个 ref 来存储 textInput 的 DOM 元素
this.inputElement = null;
this.setTextInputRef = element => {this.inputElement = element;};
this.focusTextInput = () => {
// 使用原生 DOM API 使 text 输入框获得焦点
console.log(this.inputElement)
if (this.inputElement) this.inputElement.focus();};
}
componentDidMount() {
// 组件挂载后,让文本框自动获得焦点
this.focusTextInput();}
render() {
return (
<div>
<CustomTextInput
inputRef={el => this.inputElement = el}
/>
<input
type="button"
value="点击我获取焦点"
onClick={this.focusTextInput}
/>
</div>
);
}
}
在上面的例子中,App 把它的 refs 回调函数当作 inputRef props 传递给了 CustomTextInput,而且 CustomTextInput 把相同的函数作为特殊的 ref 属性传递给了 <input>。结果是,在 App 中的 this.inputElement 会被设置为与 CustomTextInput 中的 input 元素相对应的 DOM 节点。
使用
React.forwardRef
来获取传递 ref,React 传递 ref 给 fowardRef 内函数 (props, ref) => …,作为其第二个参数,然后转发到它渲染的 DOM
import React, {Component} from 'react'
const CustomTextInput = React.forwardRef((props, ref) => (
<div>
<input ref={ref} />
</div>
));
class App extends React.Component {constructor(props) {super(props);
// 创建一个 ref 来存储 textInput 的 DOM 元素
this.inputElement = React.createRef();
this.focusTextInput = () => {
// 使用原生 DOM API 使 text 输入框获得焦点
console.log(this.inputElement)
this.inputElement.current.focus();};
}
render() {
return (
<div>
<CustomTextInput
ref={this.inputElement}
/>
<input
type="button"
value="点击我获取焦点"
onClick={this.focusTextInput}
/>
</div>
);
}
}