React 中 Cannot assign to ‘current’ because it is a read-only property 错误

当我们使用 null 值初始化 ref 并且在其类型中不包含 null 时,会出现错误“Cannot assign to ‘current’ because it is a read-only property”。 要解决该错误,请在 ref 的类型中包含 null,例如 const ref = useRef<string | null>(null)

下面是一个错误发生的示例。

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;

下面是一个发生错误的结果

React 中 Cannot assign to 'current' because it is a read-only property 错误

问题是,当我们将 null 作为初始值传递给 useRef 钩子并且在传递给钩子的泛型的类型中不包含 null 时,我们创建了一个不可变的 ref 对象。

为了解决这个错误,我们必须在传递给钩子泛型的类型中包含 null。

import {useEffect, useRef} from 'react';

const App = () => {
  // ?️ 在 ref 的类型中包含 null
  const ref = useRef<string | null>(null);

  useEffect(() => {
    ref.current = 'hello';
  }, []);

  return (
    <div>
      <h2>hello world</h2>
    </div>
  );
};

export default App;

我们使用联合类型在 ref 的类型中包含 null,这使其成为可变的 ref 对象。

现在示例中 ref 的类型是 string 或 null,并且可以为其当前属性分配这两种类型中的任何一种的值。

如果大家的 ref 指向 DOM 元素,情况也是如此。 我们必须将钩子键入为 const ref = useRef<HTMLElement | null>(null) 如果大家需要更改 ref 的当前属性的值。

请注意,如果大家不直接分配给它的当前属性,则不必在 ref 的类型中包含 null 。

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 用于聚焦输入元素。 因为它的 .current 属性没有赋值,所以没有必要在其类型中包含 null。