成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

避不開的 setState 問題

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

[[422711]]

本文轉載自微信公眾號「勾勾的前端世界」,作者西嶺 。轉載本文請聯系勾勾的前端世界公眾號。

異步的 setState

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

這是一個面試中經常會被問到的經典面試題。

在開始講解異步特性之前,我們需要先明確,從 API 層面上說,它就是普通的調用執行的函數 ,自然是同步 API 。因此,這里所說的同步和異步,指的是 API 調用后,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.       <div> 
  19.         <h2>State 組件</h2> 
  20.         <p>{this.state.name}</p> 
  21.         <buttononClick={()=>{this.fun()}}>點我</button> 
  22.       </div> 
  23.     ) 
  24.   } 
  25.  
  26. exportdefault States 

代碼實現的的功能非常簡單,就是在點擊按鈕后,修改 state 中的 name 屬性值。事件處理函數中,是在調用 setState 方法之后,又將 state 的值打印到了控制臺。運行代碼你會發現, Dom 中的值發生了改變,但是控制臺卻是之前的結果值。

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

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

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

那么,如果我想調整代碼獲取異步執行結果,應該怎么做呢?

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

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

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

當然可以!

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

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

setState 的執行邏輯

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

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

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

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

那么,這兩者又有什么區別呢?

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

兩次函數執行操作:

  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.   } 

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

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

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

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

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

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

(B站賬號:西嶺老濕)

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

當然,你可能也發現了一個問題,我們說了那么多關于組件狀態的問題,各種實驗編碼都是在 class 類組件中完成的,那函數組件中是不是和類組件一樣呢?

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

截至到目前,我們已經掌握了組件的概念、組件的傳值、以及組件狀態的相關內容。

 

責任編輯:武曉燕 來源: 勾勾的前端世界
相關推薦

2020-06-16 14:23:28

算法網絡Google

2015-09-18 11:28:23

2015-03-31 10:11:51

戴爾云計算DELL

2022-06-13 06:20:42

setStatereact18

2021-03-12 10:12:09

etState函數React

2017-04-12 11:15:52

ReactsetState策略

2020-02-23 18:00:18

數據泄露漏洞黑客

2021-06-29 09:47:34

ReactSetState機制

2022-02-25 08:54:50

setState異步React

2022-08-09 09:34:32

Spring開發

2022-08-08 17:38:45

Spring策略事務

2017-01-16 17:17:23

存儲超融合架構新聞

2023-04-12 08:18:40

ChatGLM避坑微調模型

2021-08-16 18:52:09

同步異步React

2009-05-11 14:48:11

2019-01-24 10:18:25

機器學習深度學習圖像處理

2023-05-23 07:51:57

硬盤顆粒SSD

2016-04-06 09:58:46

移動·開發技術周刊

2024-04-03 12:30:00

C++開發

2024-04-24 13:45:00

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: www.久久.com | 91观看 | 丝袜天堂 | 亚洲在线一区二区 | 国产成人免费在线 | 久久久久久99 | 成人亚洲视频 | 黑人中文字幕一区二区三区 | 日韩综合 | 国产精品视频网 | 在线视频一区二区 | 成人毛片视频在线播放 | 九九av| 黄色在线观看 | 亚洲一区二区视频在线播放 | 日本一区二区三区在线观看 | 亚洲综合99| 国产午夜视频 | 欧美日韩1区2区3区 欧美久久一区 | 久久黄色| 日韩国产精品一区二区三区 | 国产欧美日韩一区 | 国产一区视频在线 | 九色 在线 | 亚洲福利在线观看 | 欧美一区二区三区久久精品 | 亚洲成人精品 | 99reav| 国产精品美女久久久 | 亚洲成人av在线 | 暴草美女| 在线免费观看欧美 | 国产精品日韩一区 | 国产羞羞视频在线观看 | 久久不卡区 | 日本91av视频 | 在线视频成人 | 精品美女在线观看 | 337p日本欧洲亚洲大胆 | 久久久久久久久毛片 | 国产精品99久久久久久www |