日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
避不開的setState問題

本文轉(zhuǎn)載自微信公眾號「勾勾的前端世界」,作者西嶺 。轉(zhuǎn)載本文請聯(lián)系勾勾的前端世界公眾號。

我們提供的服務(wù)有:成都做網(wǎng)站、網(wǎng)站設(shè)計、外貿(mào)營銷網(wǎng)站建設(shè)、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、新巴爾虎右ssl等。為近1000家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的新巴爾虎右網(wǎng)站制作公司

異步的 setState

“setState 是異步還是同步的?”

這是一個面試中經(jīng)常會被問到的經(jīng)典面試題。

在開始講解異步特性之前,我們需要先明確,從 API 層面上說,它就是普通的調(diào)用執(zhí)行的函數(shù) ,自然是同步 API 。因此,這里所說的同步和異步,指的是 API 調(diào)用后,state 的改變或者更新 DOM 的時機,是同步還是異步的。

我們先來看一段代碼:

 
 
 
  1. import React, { Component } from'react' 
  2.  
  3. exportclass States extends Component { 
  4.   state = { 
  5.     name:"lisi", 
  6.     age:18 
  7.   } 
  8.  
  9.   fun= ()=>{ 
  10.     this.setState({ 
  11.       name:'xiling' 
  12.     }) 
  13.     console.log(this.state.name) 
  14.   } 
  15.  
  16.   render() { 
  17.     return ( 
  18.       
     
  19.         

    State 組件

     
  20.         

    {this.state.name}

     
  21.         {this.fun()}}>點我 
  22.       
 
  •     ) 
  •   } 
  •  
  • exportdefault States 
  • 代碼實現(xiàn)的的功能非常簡單,就是在點擊按鈕后,修改 state 中的 name 屬性值。事件處理函數(shù)中,是在調(diào)用 setState 方法之后,又將 state 的值打印到了控制臺。運行代碼你會發(fā)現(xiàn), Dom 中的值發(fā)生了改變,但是控制臺卻是之前的結(jié)果值。

    如果你對異步的運行規(guī)則比較熟悉,你一定不會感到奇怪。很顯然,this.setState() 是異步執(zhí)行的,調(diào)用之后,后面的代碼就緊跟著執(zhí)行了,因此,控制臺打印的結(jié)果肯定是修改之前。

    因此,我們可以確定,this.setState() 確實是異步調(diào)用執(zhí)行的代碼。

    注意,此時,你可以將 this.setState() 當(dāng)作普通的異步執(zhí)行代碼(再次強調(diào) JSX 就是 JS)。

    那么,如果我想調(diào)整代碼獲取異步執(zhí)行結(jié)果,應(yīng)該怎么做呢?

    既然可以看作為普通的異步代碼,想想也知道,其實 this.setState() 方法還提供了第二個參數(shù),我們可以傳入一個回調(diào)函數(shù),這個函數(shù)就是異步結(jié)束后執(zhí)行的回調(diào)函數(shù),具體代碼修改如下:

     
     
     
    1. fun=async ()=>{ 
    2.     awaitthis.setState({ 
    3.       name:'xiling' 
    4.     },()=>{ 
    5.       console.log(this.state.name) 
    6.     }) 
    7.   } 

    回調(diào)函數(shù)處理異步結(jié)果本來就是傳統(tǒng)的異步編碼方式,但是,我們也知道,異步中的回調(diào)函數(shù)有一個最大的問題就是 “回調(diào)地獄”,那么既然是異步,我們是不是就可以封裝一個 Promise 了呢?

    當(dāng)然可以!

    但是,封裝一個 Promise 就顯得有些復(fù)雜。最簡單的方式就是借助 ES 2017 中異步調(diào)用函數(shù) async/ await 來實現(xiàn)。我們直接修改事件處理函數(shù)即可,具體語法規(guī)則如下:

     
     
     
    1. fun=async ()=>{ 
    2.     awaitthis.setState({ 
    3.       name:'xiling' 
    4.     }) 
    5.     console.log(this.state.name) 
    6.   } 

    setState 的執(zhí)行邏輯

    在使用 this.setState() 進行狀態(tài)更改時,需要進行邏輯處理應(yīng)該怎么做呢?

    其實 this.setState() 的第一個參數(shù)是可以接收一個函數(shù)處理的。需要注意的是,函數(shù)的運行必須返回一個 state 對象,具體代碼如下:

     
     
     
    1. fun = ()=>{ 
    2.     this.setState((state)=>{ 
    3.       // 函數(shù)邏輯代碼 …… 
    4.       let returnData 
    5.       returnData = state.age+1 
    6.       // 最終返回一個state 對象 
    7.       return { 
    8.         age:returnData 
    9.       } 
    10.     }) 
    11.   } 

    也就是說 this.setState() 既可以接收對象參數(shù),也可以接收一個處理函數(shù)。

    那么,這兩者又有什么區(qū)別呢?

    在時間處理函數(shù)中,我們分別使用兩次 this.setState() 對 state 進行修改操作。

    兩次函數(shù)執(zhí)行操作:

     
     
     
    1. fun = ()=>{ 
    2.     this.setState((state)=>{ 
    3.       return { 
    4.         age:state.age+2 
    5.       } 
    6.     }) 
    7.  
    8.     this.setState((state)=>{ 
    9.       return { 
    10.         age:state.age+3 
    11.       } 
    12.     }) 
    13.   } 

    運行代碼可以發(fā)現(xiàn),兩次 this.setState() 中的函數(shù)都得到了執(zhí)行,修改了 state 的值。我們再將同樣的代碼邏輯,使用對象數(shù)據(jù)的方式進行修改操作:

     
     
     
    1. fun = ()=>{ 
    2.     this.setState({ 
    3.       age:this.state.age+2 
    4.     }) 
    5.     this.setState({ 
    6.       age:this.state.age+3 
    7.     }) 
    8.   } 

    結(jié)果顯示,只有最后一次 this.setState() 得到了執(zhí)行。

    沒錯,this.setState() 如果是函數(shù),那么函數(shù)會依次從上往下執(zhí)行;而如果是一個對象, React 會將多次 this.setState() 的調(diào)用合并為一次執(zhí)行,如果修改了相同的值,則會將前面的修改替換成最后一次的修改數(shù)據(jù)。

    這一點在項目編碼中一定要牢記,避免出現(xiàn)意外的邏輯 Bug。

    你可能會問,這到底是什么原理呢?我曾經(jīng)針對這個問題做過一場專門的技術(shù)分享直播,直播的錄屏回放在這里,感興趣可以看看:https://www.bilibili.com/video/BV19P4y1W7hX。

    (B站賬號:西嶺老濕)

    但是,對于新手來說,我建議你先收藏,因為你現(xiàn)在真的可能看不懂。

    當(dāng)然,你可能也發(fā)現(xiàn)了一個問題,我們說了那么多關(guān)于組件狀態(tài)的問題,各種實驗編碼都是在 class 類組件中完成的,那函數(shù)組件中是不是和類組件一樣呢?

    嗯~ o( ̄▽ ̄)o……,因為 state 是類組件中的特性,而函數(shù)組件中的 state,需要具備 Hook 特性的知識作為鋪墊,所以,暫時我們先留個坑,等著后面來填就行了。

    截至到目前,我們已經(jīng)掌握了組件的概念、組件的傳值、以及組件狀態(tài)的相關(guān)內(nèi)容。


    標題名稱:避不開的setState問題
    地址分享:http://www.5511xx.com/article/ccdsjgs.html