• 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

  • 相关阅读:
    VSCode 配置 Python 开发环境
    出现:Microsoft Visual C++ 14.0 is required 的解决方案
    python3 pathlib库中的Path类的使用
    使用 AI 绘制箭头
    Adobe Illustrator 入门 新建 保存图片
    jinja2
    Java 读取和写入文本文件
    Affy包 estrogen包
    GEOquery
    apply() 函数家族介绍
  • 原文地址:https://www.cnblogs.com/full-stack-engineer/p/14205082.html
Copyright © 2020-2023  润新知