Web高级 React setState同步异步

都知道React的类组件在setState的时候有异步和同步的区别,但是具体哪些是同步哪些是异步?

原理在这里就不细说了,感兴趣的同学可以看看源码:源码有个inBatchUpdate的Flag,在React自身的事件流/生命周期中这个Flag是true,setState请求会放入一个队列里,在做更新的时候会进行合并。但是React自身事件流意外的时候这个Flag是false,那么setState请求会同步执行。

看下面代码

import React from 'react';

export default class SetStateTest extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = { stateName: "init" }
        this.handleSynSet = this.handleSynSet.bind(this);
        this.handleDom2EventSet = this.handleDom2EventSet.bind(this);
        this.handlePromiseSet = this.handlePromiseSet.bind(this);
        this.handleAwaitSet = this.handleAwaitSet.bind(this);
    }

    handleSynSet() {
        this.setState({ stateName: "synClick1" });
        console.log(this.state.stateName);
        this.setState({ stateName: "synClick2" });
        console.log(this.state.stateName);
    }

    handleDom2EventSet() {
        this.setState({ stateName: "domClick1" });
        console.log(this.state.stateName);
        this.setState({ stateName: "domClick2" });
        console.log(this.state.stateName);
    }

    componentDidMount() {
        this.setState({ stateName: "mount1" });
        console.log(this.state.stateName);
        this.setState({ stateName: "mount2" });
        console.log(this.state.stateName);

        document.getElementById("dom2Event").addEventListener("click", this.handleDom2EventSet);
    }

    componentWillUnmount() {
        document.getElementById("dom2Event").removeEventListener("click", this.handleDom2EventSet);
    }

    handlePromiseSet() {
        new Promise((resolve, reject) => {
            this.setState({ stateName: "promise1" });
            console.log(this.state.stateName);
            this.setState({ stateName: "promise2" });
            console.log(this.state.stateName);
            return resolve("promise3");
        }).then((result) => {
            this.setState({ stateName: "promise4" });
            console.log(this.state.stateName);
            this.setState({ stateName: "promise5" });
            console.log(this.state.stateName);
        });
    }

    async handleAwaitSet() {
        const awaitResult = await new Promise((resolve, reject) => resolve("await1"));
        this.setState({ stateName: "await2" });
        console.log(this.state.stateName);         
        this.setState({ stateName: "await3" });
        console.log(this.state.stateName);

    }

    render() {
        return (
            <div>
                <div>
                    <button onClick={this.handleSynSet}>Synthetic SetState</button>
                    <button id="dom2Event">Dom2 Event SetState</button>
                    <button onClick={this.handlePromiseSet}>Promise SetState</button>
                    <button onClick={this.handleAwaitSet}>Await SetState</button>
                </div>
                <div>
                    <span>stateName:{this.state.stateName}</span>
                </div>
            </div>
        )
    }
}

依次点击按钮,所有的console的输出结果:

init
init
mount2
mount2
domClick1
domClick2
domClick2
domClick2
promise4
promise5
await2
await3

原文地址:https://www.cnblogs.com/full-stack-engineer/p/14205082.html