Javascript 有人能从事件循环的角度给我解释一下吗?

Javascript 有人能从事件循环的角度给我解释一下吗?,javascript,reactjs,Javascript,Reactjs,我这里有下面的代码片段 ****** Example.js ******* import React from 'react'; export default const SampleApp = props => { const [text, setText] = React.useState('Some name in here'); console.log(`[1] The value of the text is - ${tex

我这里有下面的代码片段

****** Example.js *******

    import React from 'react';

    export default const SampleApp =  props => {
        const [text, setText] = React.useState('Some name in here');

        console.log(`[1] The value of the text is - ${text}`); // ---(1)

        React.useEffect(() => {
            setText('Ohhh yeah ma boy');
            console.log(`[2] The value of the text is - ${text}`); // --- (2)
        }, []);

        React.useEffect(() => {
            console.log(`[3] The value of the text is - ${text}`); // --- (3)
            setText('Yare yare daze');
        }, [text]);

        console.log(`[4] The value of the text is - ${text}`); // --- (4)

        return (
            <div>{text}</div>
        )
    }
我不明白为什么控制台消息中没有出现“Ohhh yeah ma boy”值

原因是否与以下代码在运行控制台消息时在控制台消息上生成值
5
的原因相同,尽管我希望它显示
0 1 2 3 4

for (var i = 0; i < 5; i++) {
    setTimeout(function() { console.log(i); }, i * 1000 );
}
for(变量i=0;i<5;i++){
setTimeout(函数(){console.log(i);},i*1000);
}

这意味着在事件循环中,useState在第二次重新渲染时已经更新了2次,而第二次useEffect仍在队列中?

在react中,在渲染周期中排队的所有状态更新都将按照它们排队的顺序异步处理,并进行批处理

根据提供的代码:

const SampleApp =  props => {
    const [text, setText] = React.useState('Some name in here');

    console.log(`[1] The value of the text is - ${text}`); // ---(1)

    React.useEffect(() => {
        setText('Ohhh yeah ma boy');
        console.log(`[2] The value of the text is - ${text}`); // --- (2)
    }, []);

    React.useEffect(() => {
        console.log(`[3] The value of the text is - ${text}`); // --- (3)
        setText('Yare yare daze');
    }, [text]);

    console.log(`[4] The value of the text is - ${text}`); // --- (4)

    return (
        <div>{text}</div>
    )
}
  • [1]
    控制台作为意外副作用运行,状态为
    'Some name in here'
    ,然后
    [4]
    控制台也作为意外副作用运行,状态为
    'Some name in here'
    。渲染完成后,运行
    useffect
    钩子,首先是“onMount”效果日志记录
    [2]
    ,然后是第二次日志记录
    [3]
    ,两者都带有状态
    'Some name in here'
  • 挂载效果挂钩排队等待状态更新
    'Ohhh yeah ma boy'
  • 第二个效果是排队等待状态更新
    'Yare Yare daze'
  • 这两个排队更新都会触发重新渲染器,并在下一个渲染周期之前进行处理。状态更新为
    'Ohhh-yeah-ma-boy'
    ,然后更新为
    'Yare-Yare-daze'
  • 下一个渲染周期将显示输出
  • [1]
    控制台作为一种非故意的副作用运行与状态
    'Yare-Yare-daze'
    ,然后
    [4]
    控制台也作为一种非故意的副作用运行与状态
    'Yare-Yare-daze'
    。渲染完成第二次
    useffect
    钩子运行后,使用状态
    “Yare Yare daze”记录
    [3]
  • 第二个效果是钩子排队等待状态更新
    'Yare-Yare-daze'
  • 排队更新会触发重新渲染器,并在下一个渲染周期之前进行处理。状态更新为
    'Yare Yare daze'
  • 下一个“渲染周期”将显示输出 请注意,我在渲染周期周围加了引号

  • 作为React协调过程的一部分,组件将在“渲染阶段”渲染,以便计算ReactTree差异。由于状态与前一渲染结果的值相同,因此React为
  • [1]
    控制台作为一种非故意的副作用运行与状态
    'Yare-Yare-daze'
    ,然后
    [4]
    控制台也作为一种非故意的副作用运行与状态
    'Yare-Yare-daze'
  • 下面的react生命周期图应该有助于区分组件渲染到计算ReactTree差异时的“渲染阶段”和组件渲染到DOM时的“提交阶段”。请注意,效果是在“提交阶段”运行的

    问题 我不明白为什么“Ohhh yeah ma boy”值没有出现在 控制台消息

    如上所述,第一个排队状态更新被第二个排队状态更新覆盖,因此您根本看不到它

    这与下面代码产生错误的原因相同吗 当我运行控制台消息时,控制台消息上的值为5 希望它显示0 1 2 3 4

    for (var i = 0; i < 5; i++) {
        setTimeout(function() { console.log(i); }, i * 1000 );
    }
    
    for(变量i=0;i<5;i++){
    setTimeout(函数(){console.log(i);},i*1000);
    }
    

    不,不是真的。在本例中,您实例化了5个超时,然后对正在记录的变量
    i
    进行变异。换句话说,每个超时回调引用相同的变量(以及内存中的值),for循环会改变该值,因此当超时过期时,它们都会记录
    i
    的当前值,即
    5

    ,我强烈建议使用它来可视化运行代码的事件循环。请记住,react循环与浏览器事件循环不同。我可能是错的,但我认为状态更改是异步的,因此状态在两个useEffects都运行之前不会完成更新。@evolutionxbox loupe无法使用react代码=(我认为useEffects依赖项“text”在更新时起作用并更新dom,
    [1] The value of the text is - Some name in here
    [4] The value of the text is - Some name in here
    [2] The value of the text is - Some name in here
    [3] The value of the text is - Some name in here
    
    [1] The value of the text is - Yare yare daze
    [4] The value of the text is - Yare yare daze
    [3] The value of the text is - Yare yare daze
    
    [1] The value of the text is - Yare yare daze
    [4] The value of the text is - Yare yare daze
    
    for (var i = 0; i < 5; i++) {
        setTimeout(function() { console.log(i); }, i * 1000 );
    }