av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

React中setState同步更新策略

setState 同步更新

創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),鷹潭企業(yè)網(wǎng)站建設(shè),鷹潭品牌網(wǎng)站建設(shè),網(wǎng)站定制,鷹潭網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,鷹潭網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。

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

 
 
 
 
  1. componentDidMount() { 
  2.     fetch('https://example.com') 
  3.         .then((res) => res.json()) 
  4.         .then( 
  5.             (something) => { 
  6.                 this.setState({ something }); 
  7.                 StatusBar.setNetworkActivityIndicatorVisible(false); 
  8.             } 
  9.         ); 

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

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

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

完成回調(diào)

setState函數(shù)的第二個參數(shù)允許傳入回調(diào)函數(shù),在狀態(tài)更新完畢后進(jìn)行調(diào)用,譬如:

 
 
 
 
  1. this.setState({ 
  2.      load: !this.state.load, 
  3.      count: this.state.count + 1 
  4.    }, () => { 
  5.      console.log(this.state.count); 
  6.      console.log('加載完成') 
  7.    }); 

這里的回調(diào)函數(shù)用法相信大家很熟悉,就是JavaScript異步編程相關(guān)知識,我們可以引入Promise來封裝setState:

 
 
 
 
  1. setStateAsync(state) { 
  2.     return new Promise((resolve) => { 
  3.       this.setState(state, resolve) 
  4.     }); 
  5.   } 

setStateAsync 返回的是Promise對象,在調(diào)用時我們可以使用Async/Await語法來優(yōu)化代碼風(fēng)格:

 
 
 
 
  1. async componentDidMount() { 
  2.    StatusBar.setNetworkActivityIndicatorVisible(true) 
  3.    const res = await fetch('https://api.ipify.org?format=json') 
  4.    const {ip} = await res.json() 
  5.    await this.setStateAsync({ipAddress: ip}) 
  6.    StatusBar.setNetworkActivityIndicatorVisible(false) 
  7.  } 

這里我們就可以保證在setState渲染完畢之后調(diào)用外部狀態(tài)欄將網(wǎng)絡(luò)請求狀態(tài)修改為已結(jié)束,整個組件的完整定義為:

 
 
 
 
  1. class AwesomeProject extends Component { 
  2.   state = {} 
  3.   setStateAsync(state) { 
  4.     ... 
  5.   } 
  6.   async componentDidMount() { 
  7.    ... 
  8.   } 
  9.   render() { 
  10.     return ( 
  11.        
  12.          
  13.           My IP is {this.state.ipAddress || 'Unknown'} 
  14.          
  15.        
  16.     ); 
  17.   } 

傳入狀態(tài)計算函數(shù)

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

 
 
 
 
  1. this.setState(function(prevState, props){  
  2. return {showForm: !prevState.showForm}  
  3. }); 

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

 
 
 
 
  1. class Counter extends React.Component{ 
  2.   constructor(props){ 
  3.     super(props); 
  4.     this.state = {count : 0}  
  5.     this.incrementCount = this.incrementCount.bind(this) 
  6.   } 
  7.   incrementCount(){ 
  8.     ... 
  9.   } 
  10.   render(){ 
  11.     return 
     
  12.               Increment 
  13.               
    {this.state.count}
     
  14.           
 
  •   } 
  • 直觀的寫法我們可以連續(xù)調(diào)用兩次setState函數(shù),這邊的用法可能看起來有點怪異,不過更多的是為了說明異步更新帶來的數(shù)據(jù)不可預(yù)測問題。

     
     
     
     
    1. incrementCount(){ 
    2.    this.setState({count : this.state.count + 1})  
    3.    this.setState({count : this.state.count + 1}) 
    4.  } 

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

     
     
     
     
    1. incrementCount(){ 
    2.   this.setState((prevState, props) => ({ 
    3.      count: prevState.count + 1 
    4.    })); 
    5.   this.setState((prevState, props) => ({ 
    6.      count: prevState.count + 1 
    7.    })); 
    8.  } 

    這里的第二個setState傳入的prevState值就是***個setState執(zhí)行完畢之后的計數(shù)值,也順利保證了連續(xù)自增兩次。

    【本文是專欄作者“張梓雄 ”的原創(chuàng)文章,如需轉(zhuǎn)載請通過與作者聯(lián)系】

    戳這里,看該作者更多好文


    網(wǎng)頁標(biāo)題:React中setState同步更新策略
    網(wǎng)站網(wǎng)址:http://uogjgqi.cn/article/djeihco.html
    掃二維碼與項目經(jīng)理溝通

    我們在微信上24小時期待你的聲音

    解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流