gpt4 book ai didi

javascript - useEffect 的回调的 return 语句什么时候执行?

转载 作者:行者123 更新时间:2023-12-03 18:43:07 25 4
gpt4 key购买 nike

我想澄清一下我对这里发生的事情的理解。任何能提高我目前理解的细节都将不胜感激。

function Timer() {

let [time, setTime] = useState(5);

useEffect(() => {
let timer = setInterval(() => {
setTime(time - 1);
}, 1000)
return () => clearInterval(timer);
}, );

return <div>{time}</div>
}

export default Timer
https://codesandbox.io/s/cranky-chaplygin-g1r0p
  • time正在初始化为 5 .
  • useEffect被读取。它的回调必须准备好稍后触发。
  • div被渲染。
  • useEffect的回调被执行。 setInterval的回调准备触发。当然 useEffectreturn语句不会在这里触发,因为如果触发它会取消计时器(并且计时器确实有效)。
  • 大约 1 秒后,setInterval的回调触发更改 time 的状态(至 4)。
  • 现在一个状态已经改变,函数被重新执行。 time ,一个新变量,被初始化为新的时间状态。
  • 一个新的useEffect被读取,它的回调准备好稍后触发。 (发生这种情况是因为没有 useEffect() 的第二个参数)。
  • 组件函数的return语句被执行。这有效地重新渲染了 div .
  • 在某些时候,之前的 useEffectreturn语句执行(这会禁用之前的 timer 中的 useEffect )。我不确定何时会发生这种情况。
  • '新' useEffect的回调被执行。
  • 最佳答案

    您对事件顺序的理解是正确的。唯一缺少的是效果回调和清理的精确时间。
    当组件重新渲染时,任何 useEffect s 将对它们的依赖数组进行更改分析。如果有更改,则该效果回调将运行。这些回调保证按照它们在组件中声明的顺序运行。例如,在下面,a将始终在 b 之前记录.

    const App = () => {
    const [num, setNum] = React.useState(0);
    React.useEffect(() => {
    setInterval(() => {
    setNum(num => num + 1);
    }, 1000);
    }, []);
    React.useEffect(() => {
    console.log('a', num);
    }, [num]);
    React.useEffect(() => {
    console.log('b', num);
    }, [num]);
    return num;
    }

    ReactDOM.render(<App />, document.querySelector('.react'));
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <div class='react'></div>

    这些效果回调将运行 shortly after the browser re-paints .
    现在将效果清理回调添加到组合中。这些将始终在渲染的效果回调运行之前同步运行。例如,假设组件从 Render A 开始,在 Render A 中,一个效果 Hook 返回了一个清理回调。然后,一些状态发生了变化,并且发生了到 Render B 的转换,并且存在一个 useEffect使用包含状态更改的依赖项数组。将会发生的是:
  • 对于渲染 B
  • ,将使用新的 Prop /状态调用功能组件
  • 组件在函数结束时返回新标记
  • 必要时浏览器重绘屏幕
  • 渲染 A 的清理功能 将运行
  • 来自渲染 B 的效果回调 将运行

  • 您可以查看最后两个操作的源代码 here :
    commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);
    commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
    第一次调用会调用之前渲染的所有清理回调。第二个调用调用当前渲染的所有效果回调。当前渲染效果回调在执行之前的渲染清理回调之后同步运行。

    关于javascript - useEffect 的回调的 return 语句什么时候执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65225094/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com