函数组件在 React 中不能有字符串引用

当我们在函数组件中使用字符串作为引用时,会出现“Function components cannot have string refs”的错误。 要解决该错误,请使用 useRef() 钩子获取一个可变的 ref 对象,我们可以将其用作组件内部的 ref。

下面是产生上述错误的示例代码

export default function App() {
  // A string ref has been found within a strict mode tree.
  // ⛔️ Function components cannot have string refs.
  // We recommend using useRef() instead.
  return (
    <div>
      <input type="text" id="message" ref="msg" />
    </div>
  );
}

函数组件在 React 中不能有字符串引用

代码片段中的问题是我们使用字符串作为引用。

要解决该错误,请改用 useRef 钩子来获取可变引用对象。

import {useEffect, useRef} from 'react';

export default function App() {
  const refContainer = useRef(null);

  useEffect(() => {
    // 👇️ this is reference to input element
    console.log(refContainer.current);

    refContainer.current.focus();
  }, []);

  return (
    <div>
      <input type="text" id="message" ref={refContainer} />
    </div>
  );
}

useRef() 钩子可以传递一个初始值作为参数。 该钩子返回一个可变的 ref 对象,其 .current 属性被初始化为传递的参数。

当我们将 ref prop 传递给元素时,例如 ,React将ref对象的.current属性设置为对应的DOM节点。

需要注意的是,当你更改 ref 的当前属性的值时,不会导致重新渲染。

例如,ref 不必包含在 useEffect 钩子的依赖项数组中,因为更改它的当前属性不会导致重新渲染。

import {useEffect, useRef} from 'react';

export default function App() {
  const refContainer = useRef(null);

  const refCounter = useRef(0);

  useEffect(() => {
    // 👇️ this is reference to input element
    console.log(refContainer.current);
    refContainer.current.focus();

    // 👇️ incrementing ref value does not cause re-render
    refCounter.current += 1;
    console.log(refCounter.current);
  }, []);


  return (
    <div>
      <input type="text" id="message" ref={refContainer} />
    </div>
  );
}

示例中的 useEffect 钩子只运行了 2 次,因为 useRef 在其内容更改时不会通知我们。

更改对象的当前属性不会导致重新渲染。