React [已解决]中的useRef“对象可能为空”错误

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 上与其类型对应的属性。

useref 对象可能为空

下面是错误如何发生的示例。

应用程序.tsx
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要解决该错误,请在访问其属性之前使用类型保护从引用的类型中排除。

应用程序.tsx
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 语句作为
类型保护
来确保
currentref 上的属性不存储null值。

TypeScript 知道一旦我们进入块,对象current的属性ref就不会存储值nullif

确保使用挂钩上的泛型正确useRef键入引用的属性 current

请注意,我们传递了一个泛型来将ref的值类型
化为一个
HTMLInputElement.

DOM 元素的类型一致命名为. 一旦您开始输入,您的 IDE 应该能够帮助您自动完成。 HTML***ElementHTML..

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.

App.tsx
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).

In other words, if the 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.

App.tsx
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> ); }
The exclamation mark is called the non-null assertion operator in TypeScript. It is used to remove 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.