React、React Hooks、Diffrent console.log 在 useEffect 中打印顺序

React, React Hooks, Diffrent console.log print order inside useEffect

我收到了两份不同的 console.log 打印订单,具体取决于我是否使用承诺。

状态:

let [data,setData] = useState(1);

使用 promise 时:

let asyncFunk = async () => {
      return "Asd";
    };

    useEffect(() => {
        asyncFunk().then((result) => {
            console.log("BEFOR SET DATA " +data);
            setData(prev => prev +1 );
            console.log("AFTER SET DATA " +data);
        });
    },[]);

    return (
       <div>
            {console.log("Data in return " + data)}
        </div>
    );
}

console.log打印顺序是:

Data in return 1
BEFOR SET DATA 1
Data in return 2
AFTER SET DATA 1

因此,当调用 setData() 时,组件会重新呈现,并且 return 中的 console.log 在 setData() 之后的 console.log 之前被调用。

当我删除异步函数时:

 useEffect(() => {
            console.log("BEFOR SET DATA " +data);
            setData(prev => prev +1 );
            console.log("AFTER SET DATA " +data);
    },[]);
    return (
        <div>
            {console.log("Data in return " + data)}
        </div>
    );
}

console.log打印顺序是:

Data in return 1
BEFOR SET DATA 1
AFTER SET DATA 1
Data in return 2

当异步函数被移除时,useEffect 首先完成,并且还打印旧状态值,然后打印 return 中的 console.log。

知道这里发生了什么吗?为什么这是打印的顺序?

这是 React 的实现。

请看一下 那里说的。

TL;DR – if the state changes are triggered asynchronously (e.g. wrapped in a promise), they will not be batched; if they are triggered directly, they will be batched.

如果你看一下 comment of Dan Abramov 它说

In current release, they will be batched together if you are inside a React event handler.
...
With current version, several setStates outside of event handlers (e.g. in network responses) will not be batched. So you would get two re-renders in that case.
...

所以发生了什么是预期的结果。