我试图理解在组件函数中产生副作用与在没有传入依赖项数组的效果中产生副作用(因此应该在每次渲染时触发)之间的实际区别。据我观察,它们都以相同的频率运行。我意识到效果允许在适当的时间进行清理,但我只是对清理不是一个因素的情况感到好奇。
下面的 CodePen 展示了我在说什么。
https://codepen.io/benrhere/pen/GRyvXZZ
重要的是:
function EffectVsFunctionQuestion() {
const [count, setCount] = React.useState(0);
React.useEffect(()=>{
console.log("incremented within hook")
});
console.log("incremented within component function")
...
}
最佳答案
从 useEffect
Hook 发出的副作用的好处是每个渲染周期最多 触发一次。这里的渲染周期意味着 React 计算下一个 View 并将其提交给 DOM 时的“提交阶段”。
这不应与 React 在渲染组件(和子组件以及整个 ReactTree)时所说的“渲染阶段”相混淆) 来计算更改的内容和需要提交给 DOM 的内容。
React 函数组件的整个 函数体是“渲染”函数。正如您在图中看到的那样,render
或 body 中的任何意外副作用都将发生在“渲染阶段”期间,可以暂停、中止或重新启动(即再次运行) 由 react 。请注意,“渲染阶段”是纯净的,没有副作用。
组件可以使用 DOM 并运行副作用的“提交阶段”。
Why does this matter? How to tell the difference.?
React 实际上附带一个 StrictMode
component这有助于您检测意外的副作用。
Detecting unexpected side effects
Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:
- Class component
constructor
,render
, andshouldComponentUpdate
methods- Class component static
getDerivedStateFromProps
method- Function component bodies
- State updater functions (the first argument to
setState
)- Functions passed to
useState
,useMemo
, oruseReducer
这是一个演示意外副作用的示例沙盒演示。
请注意,意想不到的效果加倍。
代码:
const externalValue1 = { count: 0 };
const externalValue2 = { count: 0 };
function EffectVsFunctionQuestion() {
const [state, setState] = React.useState(0);
React.useEffect(() => {
externalValue1.count++;
console.log("incremented within hook", externalValue1.count);
});
externalValue2.count++;
console.log("incremented within component function", externalValue2.count);
return (
<button type="button" onClick={() => setState((c) => c + 1)}>
Render
</button>
);
}
关于javascript - react : Difference between side effect in component's function vs effect?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71684952/