reactjs - 反应功能组件重新渲染一次,即使状态的值没有改变
问题描述
我是 React 功能组件的新粉丝。当我阅读文档并尝试做一些实验时,我发现了一个值得怀疑的案例。
我有一个自定义钩子“ useAutoIncrement ”,它有一个setInterval,它每秒增加一个“num”。当此时间间隔触发时,主要组件会重新渲染。然后我将 setState 更改为 custom-hook 0的固定数字。正如预期的那样,主要组件不会重新渲染。到目前为止我们一直很好:)
然后尝试单击主组件中事件处理程序的“按钮”增量,主组件重新渲染,自定义挂钩也重新渲染。但是当间隔在第一次运行到 setState 值0时,奇怪的事情发生了。主要组件和自定义挂钩似乎重新渲染(我放置了一些 consolg.log 并显示出来),但在主组件和自定义挂钩的useEffect中都没有显示 console.log。
看看这张图片,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;
解决方案
当您单击按钮并触发状态更改时,您的组件已更新并重新渲染 - 您可以从上面的日志中看到这一点。
render useAutoIncrement
- 这是函数触发时组件遇到的第一条控制台消息
CustomHook render
- 这是 JS 堆栈中的下一个调用
useAutoIncrement useEffect return
- 因为您正在重新渲染,所以前一个正在卸载,导致它运行,但 react 以特定顺序执行此操作,因此您在新调用
useAutoIncrement
的 useEffect 将运行之前看到它
- 因为您正在重新渲染,所以前一个正在卸载,导致它运行,但 react 以特定顺序执行此操作,因此您在新调用
CustomHook useEffect return
- 在下一个 useEffect 中也会发生同样的事情
useAutoIncrement useEffect
- 反应现在运行 useEffect 现在前一个已清理
CustomHook useEffect
- 还有这个
useAutoIncrement useEffect interval
- 间隔准时发生
render useAutoIncrement
- 如前所述,setState 强制更新
CustomHook render
- 因为 useAutoIncrement 再次运行,
num
也更新了,即使它是相同的数字
- 因为 useAutoIncrement 再次运行,
希望这会有所帮助
推荐阅读
- php - 在 CloudSearch 上查找带有 AWS SDK for PHP 前缀的短语
- javascript - 在 v-for attr 中具有增量值
- git - 使用 Github API 在 GitHub 上查询组织内的存储库
- visual-studio - 从 Visual Studio Mac 在 android 上进行 Wifi 调试
- angularjs - 角度错误:转换在 $StateProvider.$get 处被取代
- python - PyQt 退出代码 139 堆叠小部件
- javascript - 测量同一类元素的总高度
- amazon-web-services - Lightsail 是迁移 Mac OS 服务器内容的正确解决方案吗?
- jquery - windows Chrome 放大显示半屏
- javascript - 如何在跨度内包装字母,包括标点符号和特殊字符?