本篇博客介绍 React中的Ref知识,包含函数组件和类组件
作用
Ref
在React
中,通常用来处理对DOM
的操作,例如聚焦输入框、控制子组件等等。
类组件
在类组件中,有以下三种写法:
- 字符串
- callback
- createRef
字符串
「已弃用」: 向标签的ref
属性传入一个字符串,即可在this.refs
的属性中访问到。
jsx
import React from 'react';
export default class ClassRef extends React.Component {
getRef = () => {
console.log(this.refs.abc);
};
render() {
return (
<div>
<h1>类组件Ref 使用字符串形式</h1>
<input ref="abc" type="text" />
<button onClick={this.getRef}>获取ref</button>
</div>
);
}
}
callback
使用ref
的callback
形式,将ref
赋值给一个自定义变量。
js
ref={ref => xxx = ref}
jsx
import React from 'react';
export default class ClassRef extends React.Component {
ref = '';
getRef = () => {
console.log('使用callback形式', this.ref);
};
render() {
return (
<div>
<h1>类组件Ref callback形式</h1>
<input ref={(e) => (this.ref = e)} type="text" />
<button onClick={this.getRef}>获取ref</button>
</div>
);
}
}
createRef
createRef
通常在类组件中使用,包含一个current
属性,这个属性指向指定的内容。
jsx
import React, {createRef} from 'react';
export default class ClassRef extends React.Component {
cRef = createRef();
getRef = () => {
console.log('使用createRef形式', this.cRef.current);
};
render() {
return (
<div>
<h1>类组件Ref createRef形式</h1>
<input ref={this.cRef} type="text" />
<button onClick={this.getRef}>获取ref</button>
</div>
);
}
}
函数组件
由于函数组件没有this,所以这里比类组件少一种形式
- callback
- useRef「常用」
callback
同样的,将ref
保存在一个变量中。
jsx
export default function FuncRef(props) {
let inputRef;
const getRef = () => {
console.log('使用callback形式',inputRef);
};
return (
<div>
<h1>函数组件Ref callback形式</h1>
<input ref={(e) => (inputRef = e)} type="text" />
<button onClick={getRef}>获取ref</button>
</div>
);
};
useRef
useRef
通常在函数组件中使用,同样也有一个current
属性,指向指定的内容。
jsx
export default function FuncRef() {
const getRef = () => {
console.log('使用useRef形式', handleRef.current);
};
const handleRef = useRef();
return (
<div>
<h1>函数组件Ref useRef形式</h1>
<input ref={handleRef} type="text" />
<button onClick={getRef}>获取ref</button>
</div>
);
};
注意
-
组件
ref
以上的示例代码的使用方式中虽然只举例了对原生元素的引用使用情况,但
ref
也是可以在自定义组件上使用。但这里有一个需要注意的地方:函数组件在被
ref
引用的时候,需要使用forwardRef
进行ref
转发,同时可以搭配useImperativeHandle
hook函数来控制暴露出去的内容。
jsx
import {useImperativeHandle, useRef, forwardRef} from 'react';
export default forwardRef(function FuncRef(props, ref) {
useImperativeHandle(ref, () => {
return {
a: 1,
b: 2,
ref: handleRef.current,
};
});
const handleRef = useRef();
return (
<div>
<h1>函数组件Ref 被使用的情况</h1>
<input ref={handleRef} type="text" />
</div>
);
});
useRef
和createRef
区别useRef
只能在函数组件中使用,createRef
在类组件、函数组件都可以使用useRef
具有缓存作用;若在函数组件使用createRef
,随着每次页面更新,都会创建新的createRef
总结
本文总结了React
中的Ref
在类组件和函数组件中的使用方式;虽然在目前的趋势下,主要是使用函数式组件进行开发,但也不乏在工作中会遇到之前用类组件写的项目,所以同时掌握两种类型的Ref
写法还是很有必要的。