首页 > 解决方案 > 为什么函数组件再次通过 setCount(1) 重新渲染

问题描述

代码:

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

环境:

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 />

标签: reactjsreact-hooksuse-state

解决方案


我不知道您要完成什么,但是如果您也将第二个 console.log 放在一个效果中,它不会双重记录那个。

  • 第一个日志集来自组件安装。
  • 第二个日志集来自在setTimeout.
  • 第三个(和后续的)日志集不会出现,因为状态并没有真正更新(即它被设置为相同的值)。您可以通过将初始状态设置为 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) 

编辑确定-torvalds-zqjqe


推荐阅读