javascript - react : Difference between side effec

我试图理解在组件函数中产生副作用与在没有传入依赖项数组的效果中产生副作用(因此应该在每次渲染时触发)之间的实际区别。据我观察,它们都以相同的频率运行。我意识到效果允许在适当的时间进行清理,但我只是对清理不是一个因素的情况感到好奇。

下面的 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, and shouldComponentUpdate methods
  • Class component static getDerivedStateFromProps method
  • Function component bodies
  • State updater functions (the first argument to setState)
  • Functions passed to useState, useMemo, or useReducer

这是一个演示意外副作用的示例沙盒演示。

请注意,意想不到的效果加倍。

代码:

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/

相关文章:

r - 如果列的值与另一列的值匹配,如何返回列的名称?

r - 创建一个虚拟变量,指示事件是否在过去 2 年发生

aws-lambda - SQS 到 ECS (Fargate) 或 SQS 到 Lambda 到

python - 连接到与登录到 google colab 的不同的 google 驱动器

ethereum - 扁平化智能联系人是否会降低部署成本?

google-forms - 您可以向 google forms api 提交 Restful 请求

python - 等于运算符与元组 : 'a' , 'b' == ('a' , 'b' )

reactjs - 在函数或类中使用 `useDispatch` 可以吗?

c# - c#中的整数提升(以sbyte的范围为例)

sql - 如何删除 SQL 中的重复行(Clickhouse)?