为什么再次通过setCount(1)重新渲染功能组件

时间:2020-05-04 00:26:05

标签: reactjs react-hooks use-state

代码:

https://codesandbox.io/s/amazing-sound-d20rz?file=/src/App.js

环境:

  • 反应(v16.13.1)
  • 反应(v16.12.0)
import React, { useState, useEffect } from "react";
import "./styles.css";

function AppRenderLog() {
  console.log("app render");

  return null;
}

export default function App() {
  const [count, setCount] = useState(2);

  useEffect(() => {
    console.log("do something");
  });

  setTimeout(() => {
    setCount(1);
    setCount(1);
    setCount(1);
  });

  console.log("render by setCont(1)");
  return (
    <div className="App">
      {count}
      <AppRenderLog />
    </div>
  );
}

期望输出:

render by setCont(1)
app render
do something
render by setCont(1)
app render
do something

当前输出:

render by setCont(1)
app render
do something
render by setCont(1)
app render
do something
render by setCont(1) // why? re-render App Component but effectCallback not exec, AppRenderLog Component not re-render
// why others not re-render <App />

1 个答案:

答案 0 :(得分:0)

我不知道您要完成什么,但是如果您将第二个console.log也放置在一个效果中,则不会使该记录再次重复。

  • 第一个日志集来自组件安装。
  • 第二个日志集来自setTimeout中排队的状态更新。
  • 第三个(及后续)日志集不会发生 not ,因为状态并未真正更新(即,其设置为相同的值)。您可以通过将初始状态设置为1(即useState(1))来进行测试,并且只会看到正在安装的日志集。

代码:

import React, { useState, useEffect } from "react";
import "./styles.css";

function AppRenderLog() {
  console.log("app render");
  return null;
}

export default function App() {
  const [count, setCount] = useState(2);

  useEffect(() => {
    console.log("do something");
  });

  setTimeout(() => {
    setCount(1);
    setCount(1);
    setCount(1);
  });

  useEffect(() => {
    console.log("render by setCont(1)");
  });

  return (
    <div className="App">
      {count}
      <AppRenderLog />
    </div>
  );
}

控制台日志输出

app render 
do something 
render by setCont(1) 
app render 
do something 
render by setCont(1)

初始状态为1时控制台日志输出

app render 
do something 
render by setCont(1) 

Edit determined-torvalds-zqjqe