在 React 中使用 useEffect 进行组件渲染

时间:2021-07-14 07:21:01

标签: javascript reactjs use-effect

考虑以下 React 中的虚拟代码:

import { useEffect, useState } from "react";

const Welcome = () => {
  console.log("[Welcome] rendered");

  return <h1>Hello World</h1>;
};

const App = () => {
  console.log("[App] rendered");

  const [myState, setMyState] = useState(false);

  useEffect(() => {
    console.log("[App - useEffect] Callback");
    setMyState(true);
  });

  return <Welcome />;
};

export default App;

当我运行这个应用程序时控制台上的输出是:

[App] rendered
[Welcome] rendered
[App - useEffect] Callback
[App] rendered
[Welcome] rendered
[App - useEffect] Callback
[App] rendered

第一个问题: 当没有状态更改时,为什么在控制台上第三次打印打印 [App] rendered 的最后一条消息(myStatetrue 并再次设置为 true)?如果再次渲染 App 组件,为什么在它之后不打印 [Welcome] rendered

问题说明: 当我运行应用程序时,App 组件首次在控制台上呈现消息 [App] rendered。由于 App 组件将 Welcome 作为其子组件,因此消息 [Welcome] rendered 打印在控制台上,子组件 Welcome 安装在 DOM 上,从而安装了 {{1}也是组件。一旦 App 组件安装在 DOM 上,App 钩子内的回调函数就会被执行并在控制台上打印 useEffect。此回调函数中的下一条语句将 [App - useEffect] Callback 状态变量设置为 myState(之前为 true)。因为 false 组件的状态发生了变化,它会被重新渲染。这会在控制台上打印另一个 App 语句。要呈现 [App] rendered,需要呈现 App 组件,该组件在控制台上打印 Welcome。一旦 [Welcome] rendered 组件被完全呈现(或评估),控件就会转到 App 钩子并且语句 useEffect 再次打印在控制台上。这一次,我再次将状态变量 [useEffect] Callback 设置为 myState(之前也是 true),从而不会改变上一次渲染的状态,因此没有重新渲染true 组件。因此,我不应该在控制台上看到第三个 App 消息。

第二个疑问: 对于我的第二个疑问,请考虑下面给出的稍微更改的代码(将 [App] rendered 设置为 myState,而不是之前将其设置为 false):

true

当我运行这个稍微修改过的应用程序时,控制台上的输出是:

import { useEffect, useState } from "react";

const Welcome = () => {
  console.log("[Welcome] rendered");

  return <h1>Hello World</h1>;
};

const App = () => {
  console.log("[App] rendered");

  const [myState, setMyState] = useState(false);

  useEffect(() => {
    console.log("[App - useEffect] Callback");
    setMyState(false);
  });

  return <Welcome />;
};

export default App;

如果在前面的代码中第三次打印了 [App] rendered [Welcome] rendered [App - useEffect] Callback ,那么为什么消息 [App] rendered 没有在此处第二次被记录?为什么两个代码片段的结果不一致?

附言 虚拟代码保持微不足道,因此我可以更多地关注概念而不是代码,并且我故意不在 [App] rendered 中使用任何依赖数组。

0 个答案:

没有答案
相关问题