即使状态值不变,也要对功能组件重新渲染一次

时间:2020-08-09 09:20:57

标签: reactjs react-functional-component

我是React Functional Component的新粉丝。 当我阅读文档并尝试做一些实验时,我发现了一个令人怀疑的情况。

我有一个带有 setInterval 的自定义钩子“ useAutoIncrement ”,它每秒增加一次“ num”。触发此间隔时,将重新渲染主要组件。 然后,将setState更改为自定义挂钩 0 的固定数字。不出所料,主要组件不会重新渲染。到目前为止,我们一直很好:)

然后尝试在主要组件中单击事件处理程序的“按钮”增量,主要组件重新渲染,并且自定义钩子也重新渲染。但是,当间隔是在下一次第一次运行以setState值 0 时,就会发生奇怪的事情。主要组件和自定义挂钩似乎都已重新渲染(我放置了一些consolg.log并显示了出来),但是在 useEffect 中没有显示console.log自定义钩子。

enter image description here

看一下这张图像,3条蓝线。第一条蓝线在挂钩效果间隔函数内。它将使用不变的值调用 setNum 。主要组件不应重新渲染,但似乎已经渲染。他们重新渲染了第二和第三条蓝线

有人可以向我解释此案吗? 这是我的代码:https://codesandbox.io/s/react-playground-ddqzc?file=/index.js

import React, { useState, useEffect } from 'react';
 
const useAutoIncrement = () => {
  const [num, setNum] = useState(0)

  useEffect(() => {
    console.log("useAutoIncrement useEffect")
    const interval = setInterval(() => {
      console.log("useAutoIncrement useEffect interval")
      setNum((currentNum) => {
        return 0 // return fixed number
      })
    }, 5000)

    return () => {
      console.log("useAutoIncrement useEffect return")
      clearInterval(interval)
    }
  });

  console.log("render useAutoIncrement")
  return 0
}

const CustomHook = () => {
  const initialCount = {value: 5};
  const [count, setCount] = useState(initialCount);

  const num = useAutoIncrement()
 
  const handleIncrement = () => {
    setCount((currentCount) => {
      return Object.assign({}, currentCount, {value: 2})
    });

    console.log("handleIncrement")
  }


  useEffect(() => {
    console.log("CustomHook useEffect")
    
    return () => {
      console.log("CustomHook useEffect return")
    }
  })

  console.log("CustomHook render")
 
  return (
    <div>
      <h1>{count.value}</h1>
 
      <button type="button" onClick={handleIncrement}>
        Increment
      </button>

      <p>Auto Increase Number: {num}</p>
    </div>
  );
};
 
export default CustomHook;

1 个答案:

答案 0 :(得分:1)

当您单击按钮并触发状态更改时,您的组件已更新并重新呈现-您可以从上面的日志记录中看到这一点。

  • render useAutoIncrement
    • 这是函数触发时您的组件遇到的第一个控制台消息
  • CustomHook render
    • 这是JS堆栈中的下一个调用
  • useAutoIncrement useEffect return
    • 由于您正在重新渲染,因此上一个已被卸载,从而导致运行,但反应以特定顺序执行,因此您可以在刚调用新useAutoIncrement的useEffect之前看到它
  • CustomHook useEffect return
    • 下一个useEffect在这里发生同样的事情
  • useAutoIncrement useEffect
      现在,
    • react现在可以运行useEffect了,因为前一个已被清理
  • CustomHook useEffect
    • 这也是
  • useAutoIncrement useEffect interval
    • 间隔按时发生
  • render useAutoIncrement
    • 如前所述,setState强制更新
  • CustomHook render
    • 由于useAutoIncrement再次运行,num也被更新,即使它是相同的数字

希望这对某些人有帮助