React useState 在没有变化的情况下重新运行组件函数
React useState reruns the component function on no change
在这个非常简单的演示中
import { useState } from 'react';
function App() {
const [check, setCheck] = useState(false);
console.log('App component Init');
return (
<div>
<h2>Let's get started! </h2>
<button
onClick={() => {
setCheck(true);
}}
>
ClickMe
</button>
</div>
);
}
export default App;
我在应用程序初始化时获得了一个登录,
第一次点击(状态从 false 变为 true)时,我得到了预期的另一个日志。
但是在第二次点击时我也得到了一个日志,尽管状态保持不变。(有趣的是,ReactDevTools 不会像重新渲染时那样在组件周围产生高亮效果)
对于每次后续点击都不会显示日志。
为什么会出现这个额外的日志。
这是一个 stackblitz 演示:
https://stackblitz.com/edit/react-ts-wvaymj?file=index.tsx
提前致谢
如果你控制台日志检查你可以看到...
您将获得的第一个点击 check
是 true
-> 检查状态从 false (init) => true (click) => state change => view change => log expected .
第二次点击 => 检查状态是否为真(从第一次点击开始)=> 真 => 状态未改变 => 视图未渲染。
所以。你可以试试
setCheck(!check);
给出
i get one log on app init,
upon the first click (state changes from false to true) i get another
log as expected.
But on the second click i also get a log , although the state remains
the same.(interstingly the ReactDevTools doesn't produce the highlight
effect around the component as when it is rerendered)
For every following clicks no log is displayed.
你的问题是
Why is this extra log happening?
检查 useState
Bailing Out of a State Update 部分(强调我的 ):
If you update a State Hook to the same value as the current state,
React will bail out without rendering the children or firing effects.
(React uses the Object.is
comparison algorithm.)
Note that React may still need to render that specific component again
before bailing out. That shouldn’t be a concern because React won’t
unnecessarily go “deeper” into the tree. If you’re doing expensive
calculations while rendering, you can optimize them with useMemo
.
你的问题的答案本质上是,“这就是 React 和 useState
钩子的工作方式。”我猜第二个额外的渲染是为了检查没有子组件需要更新,一旦确认,所有相同值的进一步状态更新将被忽略。
在这个非常简单的演示中
import { useState } from 'react';
function App() {
const [check, setCheck] = useState(false);
console.log('App component Init');
return (
<div>
<h2>Let's get started! </h2>
<button
onClick={() => {
setCheck(true);
}}
>
ClickMe
</button>
</div>
);
}
export default App;
我在应用程序初始化时获得了一个登录,
第一次点击(状态从 false 变为 true)时,我得到了预期的另一个日志。
但是在第二次点击时我也得到了一个日志,尽管状态保持不变。(有趣的是,ReactDevTools 不会像重新渲染时那样在组件周围产生高亮效果)
对于每次后续点击都不会显示日志。
为什么会出现这个额外的日志。 这是一个 stackblitz 演示: https://stackblitz.com/edit/react-ts-wvaymj?file=index.tsx 提前致谢
如果你控制台日志检查你可以看到...
您将获得的第一个点击 check
是 true
-> 检查状态从 false (init) => true (click) => state change => view change => log expected .
第二次点击 => 检查状态是否为真(从第一次点击开始)=> 真 => 状态未改变 => 视图未渲染。
所以。你可以试试
setCheck(!check);
给出
i get one log on app init,
upon the first click (state changes from false to true) i get another log as expected.
But on the second click i also get a log , although the state remains the same.(interstingly the ReactDevTools doesn't produce the highlight effect around the component as when it is rerendered)
For every following clicks no log is displayed.
你的问题是
Why is this extra log happening?
检查 useState
Bailing Out of a State Update 部分(强调我的 ):
If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the
Object.is
comparison algorithm.)Note that React may still need to render that specific component again before bailing out. That shouldn’t be a concern because React won’t unnecessarily go “deeper” into the tree. If you’re doing expensive calculations while rendering, you can optimize them with
useMemo
.
你的问题的答案本质上是,“这就是 React 和 useState
钩子的工作方式。”我猜第二个额外的渲染是为了检查没有子组件需要更新,一旦确认,所有相同值的进一步状态更新将被忽略。