【问题标题】:useEffect runs prior to rendering?useEffect 在渲染之前运行?
【发布时间】:2020-04-11 17:35:38
【问题描述】:
export default function Example() {

   useEffect(()=>{
       console.log('DOM has not rendered anything yet')
   });

    return (
        <div>
            Hello
        </div>
    );
}

上面的代码首先是控制台消息,然后Hello 出现在我的页面上。但是,通过调试代码,我可以看到returnuseEffect 之前。那么为什么useEffect第一次运行时看不到Hello呢?

此外,如果使用来自https://reactjs.org/docs/hooks-effect.html#example-using-hooks的代码:

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

看到第一次执行useEffect的回调时,只有按钮可见,You clicked 0 times不可见。

【问题讨论】:

  • useEffect 和传递给它的回调是两个不同的东西。
  • 在显示 hello 之前打印控制台是什么意思?你真的能看到两件事发生之间的一毫秒吗?我在效果中添加了debugger,当效果执行时,我可以看到 dom 中打印的 hello,因此即使您有毫秒级的快速视力,调试器也会证明您错了。
  • 通过调试代码可以看到回调执行时页面是空的。
  • 不,不是。不是您提供的代码。当调试器在效果中暂停时,我可以在 dom 中看到 hello。

标签: reactjs react-hooks


【解决方案1】:

查看钩子效果docs

useEffect 有什么作用?通过使用这个 Hook,你告诉 React 你的组件需要在渲染后做一些事情。 React 会记住您传递的函数(我们将其称为“效果”),并稍后在执行 DOM 更新后调用它。在这个效果中,我们设置了文档标题,但我们也可以执行数据获取或调用其他一些命令式 API。

【讨论】:

  • 你没有回答我的问题。为什么useEffect的回调运行而Hello不可见?
【解决方案2】:

尝试运行此代码并查看日志消息的顺序。


function App() {

  useEffect(() => {
    console.log('DOM has not rendered anything yet')
  });

  function hello() {
    console.log("render")
  }

  return (
    <div onClick={hello()} >
      Hello
    </div>
  );

}

useEffect 与 componentDidMount 类似,它在第一次渲染后和每次更新 dom 后运行。

上面的代码演示了先调用render,然后调用useEffect。

【讨论】:

  • 我的问题很简单,但似乎大家都误解了:为什么在useEffect的回调运行时Hello不可见?有什么好的解释吗?
  • @Unknowndeveloper 你的系统上一定有延迟,这使得你好似乎没有被绘制到屏幕上。是这样吗?在您在屏幕上看到Hello 之前调用了您的回调?实际上,useEffect 只能在屏幕更新后运行。
【解决方案3】:

这是您的代码,您可以打开开发工具并看到当调试器语句暂停您的代码时会呈现 hello。这就是 React 的行为方式,正如 2 个人已经指出的那样。

const { useState, useEffect } = React;
function App() {
  useEffect(() => {
    debugger;
    console.log('last');
  });
  console.log('first');
  //this is returned and react will render this to dom before
  //  your effect is called as documented and as 2 people already pointed out
  return <div>Hello</div>;
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

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

【讨论】:

  • 请看图。
  • @Unknowndeveloper Example 是如何呈现的?它可能在隐藏的组件中吗?也许右键单击 DOM 并检查它或查看元素选项卡以查看 DOM 是什么。
  • 绝对正常。你试过reactjs.org/docs/hooks-effect.html#example-using-hooks的代码吗?
  • @Unknowndeveloper 如果是你的浏览器有问题那么上面的代码应该也有同样的问题,可能是App如何渲染,App如何渲染Example。我正在尝试创建一个 sn-p 来重现您的体验,但使用您提供的代码(上面的代码)我无法使用我的浏览器(Chrome)重现它
  • @Unknowndeveloper 你没有使用任何实验性的反应功能是吗?喜欢concurrent
猜你喜欢
  • 1970-01-01
  • 2023-02-14
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
  • 2021-03-05
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
相关资源
最近更新 更多