原理

似乎大家对这两个hook的疑问很多,尤其是使用它们的时机,所以在这里给大家再总结一下

先看一下这段代码:

export default function App() {
  const value = { name: 1 };

  React.useEffect(() => {
    alert("render");
  }, [value]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Edit to see some magic happen!</h2>
    </div>
  );
}

首先大家需要明白的是,每次App组件渲染,value变量都会被定义一次

那么,请问上面这段代码中,App渲染几次,value被定义几次, alert 会被弹出几次?

答案是:

  1. 第一次初始化以后,没有任何事情能引起它的再次渲染(因为没有父组件、没有状态/props改变),所以只会渲染一次
  2. 因为只渲染一次,value也只会被定义一次
  3. 而useEffect的执行时机,是在组件渲染后,由于只渲染一次,所以useEffect只执行一次,所以alert只弹出一次

再看这段代码:

import "./styles.css";
import React from "react";

export default function App() {
  const [count, setCount] = React.useState(0); // 加了这一行
  const value = { name: 1 };

  React.useEffect(() => {
    setCount(Math.random()); // 加了这一行
    ("render");
  }, [value]);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Edit to see some magic happen!</h2>
    </div>
  );
}

这段代码比上一段多了两句,我已经在注释中标出来了,请问现在 App渲染几次,value被定义几次, alert 会被弹出几次呢?

答案是:无限循环,全都无限次

这里循环的原因是:组件渲染 → useEffect执行 → setCount触发循环 → 组件渲染 → useEffect执行 → setCount触发循环...

绝大多数同学遇到的无限循环的情况,都是这段代码的缩影