注释从这开始~
总览
当咱们用一个 null
值初始化一个 ref
,但在其类型中不包含null
时,就会产生 ”Cannot assign to ‘current’ because it is a read-only property” 谬误。为了解决该谬误,请在 ref
的类型中蕴含null
。比如说,const ref = useRef<string | null>(null)
。
这里有个例子来展现谬误是如何产生的。
// App.tsx
import {useEffect, useRef} from 'react';
const App = () => {const ref = useRef<string>(null);
useEffect(() => {// ⛔️ Error: Cannot assign to 'current' because it is a read-only property.ts(2540)
ref.current = 'hello';
}, []);
return (
<div>
<h2>hello world</h2>
</div>
);
};
export default App;
下面例子的问题在于,当咱们将 null
作为初始值传递到 useRef
钩子中时,并且咱们传递给钩子的泛型中没有包含 null
类型,咱们创立了一个不可变的 ref
对象。
正确的泛型
为了解决该谬误,咱们必须在传递给钩子的泛型中包含 null
类型。
// App.tsx
import {useEffect, useRef} from 'react';
const App = () => {
// 👇️ include null in the ref's type
const ref = useRef<string | null>(null);
useEffect(() => {ref.current = 'hello';}, []);
return (
<div>
<h2>hello world</h2>
</div>
);
};
export default App;
在 ref
的类型中,咱们应用联结类型来包含 null
类型,这使它成为可变 ref
对象。
当初这个例子中
ref
的类型是字符串或null
,它的current
属性能够赋值为这两种类型中的任意一种的值。
DOM 元素
如果你的援用指向一个 DOM 元素,状况也是一样的。如果你须要扭转 ref
的current
属性的值,你必须将钩子的类型定为 const ref = useRef<HTMLElement | null>(null)
。
留神,如果你不间接赋值给它的 current
属性,你不用在 ref
的类型中蕴含 null
。
// App.tsx
import {useEffect, useRef} from 'react';
const App = () => {const ref = useRef<HTMLInputElement>(null);
useEffect(() => {ref.current?.focus();
}, []);
return (
<div>
<input ref={ref} type="text" defaultValue="" />
</div>
);
};
export default App;
上述例子中的 ref
是用来聚焦 input
元素的。因为没有对其 .current
属性进行赋值,所以没有必要在其类型中蕴含null
。