日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

react同步请求_React中setState同步更新策略

發布時間:2025/3/8 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 react同步请求_React中setState同步更新策略 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

setState 同步更新

我們在上文中提及,為了提高性能React將setState設置為批次更新,即是異步操作函數,并不能以順序控制流的方式設置某些事件,我們也不能依賴于this.state來計算未來狀態。典型的譬如我們希望在從服務端抓取數據并且渲染到界面之后,再隱藏加載進度條或者外部加載提示:

componentDidMount() {

fetch('https://example.com')

.then((res) => res.json())

.then(

(something) => {

this.setState({ something });

StatusBar.setNetworkActivityIndicatorVisible(false);

}

);

}

因為setState函數并不會阻塞等待狀態更新完畢,因此setNetworkActivityIndicatorVisible有可能先于數據渲染完畢就執行。我們可以選擇在componentWillUpdate與componentDidUpdate這兩個生命周期的回調函數中執行setNetworkActivityIndicatorVisible,但是會讓代碼變得破碎,可讀性也不好。實際上在項目開發中我們更頻繁遇見此類問題的場景是以某個變量控制元素可見性:

this.setState({showForm : !this.state.showForm});

我們預期的效果是每次事件觸發后改變表單的可見性,但是在大型應用程序中如果事件的觸發速度快于setState的更新速度,那么我們的值計算完全就是錯的。本節就是討論兩種方式來保證setState的同步更新。

完成回調

setState函數的第二個參數允許傳入回調函數,在狀態更新完畢后進行調用,譬如:

this.setState({

load: !this.state.load,

count: this.state.count + 1

}, () => {

console.log(this.state.count);

console.log('加載完成')

});

這里的回調函數用法相信大家很熟悉,就是JavaScript異步編程相關知識,我們可以引入Promise來封裝setState:

setStateAsync(state) {

return new Promise((resolve) => {

this.setState(state, resolve)

});

}

setStateAsync返回的是Promise對象,在調用時我們可以使用Async/Await語法來優化代碼風格:

async componentDidMount() {

StatusBar.setNetworkActivityIndicatorVisible(true)

const res = await fetch('https://api.ipify.org?format=json')

const {ip} = await res.json()

await this.setStateAsync({ipAddress: ip})

StatusBar.setNetworkActivityIndicatorVisible(false)

}

這里我們就可以保證在setState渲染完畢之后調用外部狀態欄將網絡請求狀態修改為已結束,整個組件的完整定義為:

class AwesomeProject extends Component {

state = {}

setStateAsync(state) {

...

}

async componentDidMount() {

...

}

render() {

return (

My IP is {this.state.ipAddress || 'Unknown'}

);

}

}

該組件的執行效果如下所示:

傳入狀態計算函數

除了使用回調函數的方式監聽狀態更新結果之外,React還允許我們傳入某個狀態計算函數而不是對象來作為第一個參數。狀態計算函數能夠為我們提供可信賴的組件的State與Props值,即會自動地將我們的狀態更新操作添加到隊列中并等待前面的更新完畢后傳入最新的狀態值:

this.setState(function(prevState, props){

return {showForm: !prevState.showForm}

});

這里我們以簡單的計數器為例,我們希望用戶點擊按鈕之后將計數值連加兩次,基本的組件為:

class Counter extends React.Component{

constructor(props){

super(props);

this.state = {count : 0}

this.incrementCount = this.incrementCount.bind(this)

}

incrementCount(){

...

}

render(){

return

Increment

{this.state.count}

}

}

直觀的寫法我們可以連續調用兩次setState函數,這邊的用法可能看起來有點怪異,不過更多的是為了說明異步更新帶來的數據不可預測問題。

incrementCount(){

this.setState({count : this.state.count + 1})

this.setState({count : this.state.count + 1})

}

上述代碼的效果是每次點擊之后計數值只會加1,實際上第二個setState并沒有等待第一個setState執行完畢就開始執行了,因此其依賴的當前計數值完全是錯的。我們當然可以使用上文提及的setStateAsync來進行同步控制,不過這里我們使用狀態計算函數來保證同步性:

incrementCount(){

this.setState((prevState, props) => ({

count: prevState.count + 1

}));

this.setState((prevState, props) => ({

count: prevState.count + 1

}));

}

這里的第二個setState傳入的prevState值就是第一個setState執行完畢之后的計數值,也順利保證了連續自增兩次。

總結

以上是生活随笔為你收集整理的react同步请求_React中setState同步更新策略的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。