React 中的 useRef “Object is possible null” 错误[已解决]
useRef “Object is possibly null” error in React [Solved]
使用类型保护来解决 React 中 useRef 钩子的“Object is possible null”错误,例如if (inputRef.current) {}
.
一旦null
从 ref 的类型中排除,我们就可以访问 ref 上与其类型对应的属性。
下面是错误如何发生的示例。
import {useEffect, useRef} from 'react'; export default function App() { const inputRef = useRef<HTMLInputElement>(null); useEffect(() => { // ⛔️ Object is possibly 'null'.ts(2531) inputRef.current.focus(); }, []); return ( <div> <input ref={inputRef} type="text" id="message" /> <button>Click</button> </div> ); }
问题在于 TypeScript 无法保证我们会将 ref 分配给一个元素或为其分配一个值,因此它的current
属性可能是
null
.
使用类型保护来解决错误
null
要解决该错误,请在访问其属性之前使用类型保护从引用的类型中排除。
import {useEffect, useRef} from 'react'; export default function App() { const inputRef = useRef<HTMLInputElement>(null); useEffect(() => { // 👉️ ref could be null here if (inputRef.current != null) { // 👉️ TypeScript knows that ref is not null here inputRef.current.focus(); } }, []); return ( <div> <input ref={inputRef} type="text" id="message" /> <button>Click</button> </div> ); }
我们使用一个简单的 if 语句作为
类型保护
来确保current
ref 上的属性不存储null
值。
TypeScript 知道一旦我们进入块,对象current
的属性ref
就不会存储值。null
if
useRef
键入引用的属性 current
请注意,我们传递了一个泛型来将ref的值类型
化为一个HTMLInputElement
.
HTML***Element
HTML..
Some commonly used types are: HTMLInputElement
, HTMLButtonElement
,
HTMLAnchorElement
, HTMLImageElement
, HTMLTextAreaElement
,
HTMLDivElement
etc.
If you store a different value in your ref, make sure to pass the specific type
to the generic of the useRef
hook, e.g.
const ref = useRef<{name: string}>(null);
.
# Use the optional chaining (?.) operator to solve the error
We could have also used the
optional chaining (?.)
operator to short-circuit if the current
property on the ref stores a null
value.
import {useEffect, useRef} from 'react'; export default function App() { const inputRef = useRef<HTMLInputElement>(null); useEffect(() => { // 👇️ optional chaining (?.) inputRef.current?.focus(); }, []); return ( <div> <input ref={inputRef} type="text" id="message" /> {/* Cannot find name 'button'.ts(2304) */} <button>Click</button> </div> ); }
The optional chaining (?.) operator short-circuits instead of throwing an error
if the reference is nullish (null
or undefined
).
current
property on the ref stores a null
value, the operator would short-circuit returning undefined
instead of try to call the focus()
method on an undefined
value and cause a runtime error.# Use the non-null (!) assertion operator to solve the error
An alternative solution to the error with refs in React is to use the
non-null (!) assertion
operator.
import {useEffect, useRef} from 'react'; export default function App() { const inputRef = useRef<HTMLInputElement>(null); useEffect(() => { // 👇️ using non-null (!) assertion inputRef.current!.focus(); }, []); return ( <div> <input ref={inputRef} type="text" id="message" /> {/* Cannot find name 'button'.ts(2304) */} <button>Click</button> </div> ); }
null
and undefined
from a type without doing any explicit type checking.When we use it, we basically tell TypeScript that the current
property on the
ref object does not store a null
or an undefined
value.
Note that this approach is not type safe as TypeScript doesn’t perform any
checks to make sure the property is not nullish.
The “Object is possibly null” error is caused because the useRef()
hook can be
passed an initial value as an argument and we’re passing it null
as an initial
value.
The hook returns a mutable ref object whose .current
property is initialized
to the passed argument.
When we pass a ref prop to an element, e.g. <input ref={myRef} />
, React sets
the .current
property of the ref object to the corresponding DOM node, but
TypeScript can’t be sure that we’re going to set the ref to a DOM element or set
its value later in our code.