当使用useRef
时,我们可以访问一个可变的引用对象。我们可以将初始值传递给useRef
,它用于初始化可变ref
对象公开的属性。当试图访问函数中的一些组件时,这是很有用的。
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus(); // Error! Object is possibly 'null'
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
同样的写法,在ts
中使用时会报如下错误。因为我们用null
初始化了useRef
,这是一种有效的情况,因为有时候设置引用可能会在稍后的时间点发生。这意味着,我们在使用useRef
时需要更加明确。
function TextInputWithFocusButton() {
const inputEl = useRef<HTMLInputElement>(null); // 在ts中需要定义ref的属性类型
const onButtonClick = () => {
inputEl.current.focus(); // Error! Object is possibly 'null'
};
// ...
}
通过定义实际类型useRef<HTMLInputElement>
(不同标签属性在ts语法中会有提示)来使用useRef
时更加具体,但是仍然不能消除错误。实际检查当前属性值是否存在,将防止编译时报错。
function TextInputWithFocusButton() {
const inputEl = useRef<HTMLInputElement>(null);
const onButtonClick = () => {
if (inputEl.current) {
inputEl.current.focus() // Works!
}
// inputEl.current!.focus() 或者用这种写法也可以解决编译报错的问题
};
// ...
}
useRef
也可以用作实例变量。如果我们需要能够更新当前属性,我们需要使用useRef
的泛型类型Type || null
function sleep() {
const timeoutRefId = useRef<number | null>();
useEffect(() => {
const id = setTimeout(() => {
// ...
});
if (timeoutRefId.current) {
timeoutRefId.current = id;
}
return () => {
if (timeoutRefId.current) {
clearTimeout(timeoutRefId.current);
}
};
});
// ...
}
以上就是useRef
在ts
中的简单使用,更多内容请参考React文档
参考链接: dev.to/busypeoples…
延伸阅读:React 之受控组件和非受控组件