javascript - 有人可以从事件循环的 Angular 向我解释一下吗?

标签 javascript reactjs

我在这里有以下 react 片段

****** 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>
        )
    }
当我运行它时,它会给我以下控制台消息
    [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
我不明白为什么控制台消息中没有出现“哦,是的,男孩”的值?
是否与以下代码产生值 5 5 5 5 5 的原因相同?虽然我希望它显示 0 1 2 3 4 在我运行它时显示在控制台消息上?
for (var i = 0; i < 5; i++) {
    setTimeout(function() { 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] 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]控制台作为 运行无意的副作用有状态'Some name in here' ,然后是 [4]控制台也作为 运行无意的副作用有状态'Some name in here' .一旦渲染完成 useEffect钩子(Hook)运行,首先“onMount”效果记录[2]然后是第二次记录 [3] , 都具有状态 'Some name in here' .
  • 安装效果 Hook 将状态更新入队 'Ohhh yeah ma boy'
  • 第二个效果使状态更新入队'Yare yare daze'
  • 两个入队更新都会触发重新渲染,并在下一个渲染周期之前进行处理。状态更新为 'Ohhh yeah ma boy' ,然后更新为 'Yare yare daze' .

  • 下一个渲染周期的输出将是
    [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]控制台作为 运行无意的副作用有状态'Yare yare daze' ,然后是 [4]控制台也作为 运行无意的副作用有状态'Yare yare daze' .一旦渲染完成第二个 useEffect Hook 运行,记录 [3]有状态'Yare yare daze' .
  • 第二个效果 Hook 将状态更新入队 'Yare yare daze' .
  • 入队的更新会触发重新渲染,并在下一个渲染周期之前进行处理。状态更新为 'Yare yare daze' .

  • 下一个“渲染周期”的输出将是
    [1] The value of the text is - Yare yare daze
    [4] The value of the text is - Yare yare daze
    
    请注意,我在渲染周期周围放置了引号。
  • 作为 React 协调过程的一部分,组件在“渲染阶段”渲染以计算 ReactTree 差异。由于 state 与之前渲染结果的值相同,因此 react 为 Bailing out of a state update .
  • [1]控制台作为 运行无意的副作用有状态'Yare yare daze' ,然后是 [4]控制台也作为 运行无意的副作用有状态'Yare yare daze' .

  • 下面的 React 生命周期图应该有助于区分组件被渲染以计算 ReactTree 时的“渲染阶段”和组件被渲染到 DOM 时的“提交阶段”。请注意,效果在“提交阶段”运行
    enter image description here
    问题

    I don't get it why 'Ohhh yeah ma boy' value did not appear in the console message?


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

    Is it because of the same reason as to why the following code yields the value 5 5 5 5 5 on the console message when i run it though i expect it to show 0 1 2 3 4?

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

    不,不是。在此示例中,您实例化 5 个超时,然后改变变量 i被记录。换句话说,每个超时回调引用相同的变量(和内存中的值)并且 for 循环会改变值,因此当超时到期时,它们都会记录 i 的当前值,即 5 .

    关于javascript - 有人可以从事件循环的 Angular 向我解释一下吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66620321/

    相关文章:

    javascript - React-Material-ui : Autocomplete on words that aren't the first in a sentence

    javascript - 防止复选框和可点击表格行冲突

    javascript - Canvas 线条先变浅然后变暗

    javascript - 双击div,p,span时如何获取选中的单词?

    javascript - 如何选择在 Angular 中动态加载的 html 元素?

    javascript - 基于用户输入的条件渲染

    javascript - ReactJS 组件似乎没有独立的作用域

    javascript - 使用 UseState Hook 后 React 组件不会重新渲染

    javascript - 快速 Javascript 继承 : Understanding __proto__

    javascript - 我如何在一个 aspx 页面上对每个用户控件使用 javascript pageLoad() 事件?