首页 > 解决方案 > 为什么 ref 值在 useEffect 中是正确的,但在组件主体中是无效的

问题描述

这可能非常微不足道,但我正在寻找一个正确的答案:

为什么在 中someRef可用useEffect,但nullChild正文中?

这怎么可能?

特别是当组件不重新渲染时。看起来像是useEffect组件之上的一种抽象层?听起来很荒谬

const { useState, useRef } = React;

const Child = ({ someRef }) => {
  console.log('body', someRef);
  
  React.useEffect(() => {
     console.log('hiya', someRef);
  }, [someRef]);

  console.log('body', someRef);
  return null;
}

const App = () => {
  const someRef = useRef(null);

  return (
     <div>
      <div ref={someRef}>text1</div>
      <Child someRef={someRef} />
     </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

标签: javascriptreactjsreact-hooks

解决方案


App在第一次完全渲染并创建 HTMLElement之前,不会分配 ref 。当组件首次安装在应用程序中时,任何与元素相关的 ref 最初都不会被定义,直到初始安装周期完成。这就是useEffectinChild正确显示 ref 填充的原因<div>

您不需要等待someRefChild 中的更改(而且您不应该这样做,因为 ref 对象无论如何都不会更改) - 您需要做的就是等待初始安装完成。这也可以:

const Child = ({ someRef }) => {
  React.useEffect(() => {
     console.log('hiya', someRef);
  }, []);

你可以想到

<div ref={someRef}>

有一点像

<div onThisElementInsertedIntoDOM={function() { someRef.current = this; }}

完全是,但你明白了。当您第一次将元素记录到函数体中时,该元素尚未插入。元素可能正在创建过程中,但它们还没有进入 DOM。


推荐阅读