91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

React中setState同步或異步問題的示例分析

發布時間:2021-11-12 13:47:20 來源:億速云 閱讀:155 作者:小新 欄目:開發技術

這篇文章主要為大家展示了“React中setState同步或異步問題的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“React中setState同步或異步問題的示例分析”這篇文章吧。

    1. setState同步?異步?

    在 React 的類式組件中,我們可以使用setState方法更新state狀態。但有些時候使用setState之后,得不到最新的數據。

    其實 React 中setState本身執行的過程和代碼是同步的,只是因為 React 框架本身的性能優化機制而導致的。React 中合成事件和生命周期函數的調用順序在更新之前,導致在合成事件和生命周期函數中無法立刻得到更新后的值,形成了異步的形式。

    假如在一個合成事件中,循環調用了setState方法n次,如果 React 沒有優化,當前組件就要被渲染n次,這對性能來說是很大的浪費。所以,React 為了性能原因,對調用多次setState方法合并為一個來執行。當執行setState的時候,state中的數據并不會馬上更新。

    前面已經說到,在 React 的合成事件和生命周期函數中直接調用setState,會表現出異步的形式。

    除此之外,如果越過 React 的性能優化機制,在原生事件、setTimeout中使用setState,就會表現出同步的形式。

    2. 表現為異步

    1. React 合成事件

    在 React 中直接使用的事件,如onChange、onClick等,都是由 React 封裝后的事件,是合成事件,由 React 管理。那么由于性能優化的機制,在合成事件中直接調用setState,將表現出異步的形式。

    如下代碼,在合成事件onClick中,直接將state中的count加1,并在此之后打印count的值,結果第一次點擊按鈕時,會打印出0,而不是最新的1。

    state = { count: 0 };
    add = () => {
        this.setState({ count: this.state.count + 1 });
        console.log(this.state.count); // 0
    };
    render() {
        return (
            <>
                <div>當前計數:{this.state.count}</div>
                <button onClick={this.add}>add</button>
            </>
        );
    }

    2. 生命周期函數

    生命周期函數也是由 React 所管理,在生命周期函數中直接調用setState,也會表現出異步的形式。

    如下代碼,在生命周期componentDidMount函數中,將state中的count加1,并在此之后打印count的值,結果打印出0,而不是最新的1。

    state = { count: 0 };
    componentDidMount() {
        this.setState({ count: this.state.count + 1 });
        console.log(this.state.count); // 0
    }
    render() {
        return (
            <>
                <div>當前計數:{this.state.count}</div>
                <button>add</button>
            </>
        );
    }

    3. 表現為同步

    1. 原生事件

    setState本身執行的過程是同步的,使用原生事件,繞過 React 的管理,將表現出同步的形式。

    如下代碼,通過id獲取到 DOM 元素,用原生方法綁定點擊事件。在點擊事件中,將state中的count加1,并在此之后打印count的值,結果會打印最新的count值1。

    state = { count: 0 };
    componentDidMount() {
        const btn = document.getElementById('btn');
        btn.onclick = () => {
            this.setState({ count: this.state.count + 1 });
            console.log(this.state.count); // 1
        };
    }
    render() {
        return (
            <>
                <div>當前計數:{this.state.count}</div>
                <button id="btn">add</button>
            </>
        );
    }

    2. setTimeout

    如下代碼,在生命周期componentDidMount函數中寫了一個定時器setTimeout,在setTimeout內部將state中的count加1,并在此之后打印count的值,結果會打印最新的count值1。

    setState雖然也是寫在生命周期componentDidMount函數中的,但并不是直接寫在componentDidMount里,而是套了一層setTimeout。這樣,setState就表現出同步的形式。

    state = { count: 0 };
    componentDidMount() {
        setTimeout(() => {
            this.setState({ count: this.state.count + 1 });
            console.log(this.state.count); // 1
        }, 0);
    }
    render() {
        return (
            <>
                <div>當前計數:{this.state.count}</div>
                <button>add</button>
            </>
        );
    }

    4. setState的第二個參數

    無論setState的對象式寫法,還是函數式寫法,都有第二個參數,為可選的回調函數,這個回調函數在狀態更新完畢、界面也更新后(render調用后)才被調用。

    如下代碼所示,setState雖然直接在componentDidMount中調用,但在setState的回調函數中打印count的值,得到了最新的值1,因為回調函數在狀態更新完畢后才被調用,當然能得到最新的count了。

    state = { count: 0 };
    componentDidMount() {
        this.setState({ count: this.state.count + 1 }, () => {
            console.log(this.state.count); // 1
        });
    }
    render() {
        return (
            <>
                <div>當前計數:{this.state.count}</div>
                <button>add</button>
            </>
        );
    }

    以上是“React中setState同步或異步問題的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    玉山县| 镇赉县| 兴山县| 渭源县| 平果县| 高邮市| 类乌齐县| 晋江市| 白银市| 崇州市| 平遥县| 花垣县| 千阳县| 康保县| 周宁县| 九江县| 常山县| 赣州市| 鹰潭市| 潞城市| 浮山县| 天台县| 井陉县| 贺兰县| 商南县| 谢通门县| 泸州市| 长垣县| 佳木斯市| 出国| 闸北区| 延庆县| 紫金县| 鄂托克前旗| 若羌县| 磐石市| 越西县| 宁武县| 新郑市| 东方市| 尼勒克县|