在效果中设置状态后反应功能组件渲染两次
react functional component render twice after setState in the effect
我写的简单代码如下
import React, { useState, useEffect } from "react";
export default function App() {
const [count, setCount] = useState(1);
useEffect(() => {
setCount(2);
}, [count]);
console.info("render: ", count);
return <div>{count}</div>;
}
控制台输出为
render: 1
render: 2
render: 2
为什么“render:2”输出两次
问题是您正在无条件更新用作依赖项的状态。
这种行为并不意外。
见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
.
count
在初始渲染时为 1,第一个日志。
useEffect
挂钩运行并将状态更新排入队列并处理更新。
count
在下一次渲染时为2,第二个日志。
count
状态值已更新,因此 useEffect
挂钩回调运行并将另一个状态更新排队到相同的值并处理更新。
下次渲染时count
还是2,第三个日志。
count
状态没有改变,所以 useEffect
钩子回调没有被触发。
我写的简单代码如下
import React, { useState, useEffect } from "react";
export default function App() {
const [count, setCount] = useState(1);
useEffect(() => {
setCount(2);
}, [count]);
console.info("render: ", count);
return <div>{count}</div>;
}
控制台输出为
render: 1
render: 2
render: 2
为什么“render:2”输出两次
问题是您正在无条件更新用作依赖项的状态。
这种行为并不意外。
见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
.
count
在初始渲染时为 1,第一个日志。
useEffect
挂钩运行并将状态更新排入队列并处理更新。
count
在下一次渲染时为2,第二个日志。
count
状态值已更新,因此 useEffect
挂钩回调运行并将另一个状态更新排队到相同的值并处理更新。
下次渲染时count
还是2,第三个日志。
count
状态没有改变,所以 useEffect
钩子回调没有被触发。