在这篇文章中,我们将介绍如何在函数和类组件中使用React refs与TypeScript:

在函数组件中创建强类型的 refs
useRef 钩子可以用来访问一个元素的所有属性和方法:
const element = React.useRef(null);
// can access all the properties and methods of `element` via `element.current`
...
return (
<SomeElement ref={element} />
);
当我们需要在一个元素上调用方法时,通常会用到它,下面是一个例子:
function Search() {
const input = React.useRef(null);
React.useEffect(() => {
if (input.current) {
input.current.focus();
}
}, []);
return (
<form>
<input ref={input} type="search" />
</form>
);
};
当组件第一次渲染时,我们正在对一个input 设置焦点。
如果严格模式开启,input.current 的类型被推断为null ;否则,它被推断为any 。如果严格模式开启,在引用input.current 时也会发生类型错误。
不太理想。😞
我们可以通过传递一个通用类型参数来明确定义从useRef 返回的元素的类型:
const element = React.useRef<ElementType>(null);
因此,我们可以在Search 组件中显式地输入ref,如下所示:
const input = React.useRef<HTMLInputElement>(null);
现在类型错误消失了。😃
在类组件中创建强类型的引用
让我们把Search 组件实现为一个类组件,下面是第一次尝试:
class Search extends React.Component {
private input = React.useRef<HTMLInputElement>(null);
componentDidMount() {
if (this.input.current) {
this.input.current.focus();
}
}
render() {
return (
<form>
<input ref={this.input} type="type" />
</form>
);
}
}
虽然useRef 钩子不能在类组件中使用。😞
在类组件中,我们可以使用createRef 来获得一个元素的引用。我们可以用它来修改我们对Search 组件的实现:
class Search extends React.Component {
private input = React.createRef();
componentDidMount() {
if (this.input.current) {
this.input.current.focus();
}
}
render() {
return (
<form>
<input ref={this.input} type="type" />
</form>
);
}
}
虽然输入元素的类型被推断为unknown 。这意味着当this.input.current 被引用时,我们会得到一个类型错误。😞
我们可以通过传递一个通用类型参数来明确定义从createRef 返回的元素的类型:
React.createRef<ElementType>();
下面是Search 组件的一个修订的、更强类型的版本:
class Search extends React.Component {
private input = React.createRef<HTMLInputElement>();
componentDidMount() {
if (this.input.current) {
this.input.current.focus();
}
}
render() {
return (
<form>
<input ref={this.input} type="type" />
</form>
);
}
}
如果我们运行这段代码,我们会看到焦点在渲染后被设置在输入上。😃