一文講清楚React中setState的使用方法和機制

文章目錄

  • 一文講清楚React中setState的使用方法和機制
  • 1. setState是什么
  • 2. setState方法詳解
    • 2.1 setState參數詳解
    • 2.2 setState同步異步問題
      • 2.2.1 setState異步更新
      • 2.2.2 setState同步更新

一文講清楚React中setState的使用方法和機制

1. setState是什么

  • React中,this.setState(updater,callback)是一個方法,用來改變state的值,進而實現頁面的重新渲染
  • 不了解的先看這篇文章一文講清楚React中state和props的區別與聯系
  • 直接上例子
import React from 'react'
class App extends React.Component{constructor(props){super(props)this.state={name:'tom'}}handleClick=()=>{this.setState({name:'new tom'})}render(){return(<div><div>{this.state.name}</div><button onClick={this.handleClick}>change name in by setState</button></div>)}
}
export default App
  • 運行顯示tom,點擊按鈕通過setState方法把name改為new tom,發現頁面顯示成了new tom

2. setState方法詳解

2.1 setState參數詳解

  • setState由兩個參數,updater和callback,updater可以是對象也可以是函數
  • 我們下一個計數器的demo
import React from 'react'
class App extends React.Component{constructor(props){super(props)this.state={count:0}}handleClick=()=>{this.setState(preState=>({count:preState.count+1}))}render(){return(<div><div>{this.state.count}</div><button onClick={this.handleClick}>+1</button></div>)}
}
export default App
  • 點擊+1,也能實現狀態的改變并現實出來
  • 那么對象參數和函數參數有什么區別呢,先給出答案,如果是參數是對象,會進行事件合并,如果參數是函數,不會發生事件合并,上代碼
  • 我們設置兩個計數器,一個從參數對象更新,一個用參數函數更新,每點擊一次按鈕,計數器做三次+1操作
import React from 'react'
class App extends React.Component{constructor(props){super(props)this.state={count1:0,count2:0,}}handleClick=()=>{//第一個計數器用對象參數執行三次+1this.setState({count1:this.count1+1})this.setState({count1:this.count1+1})this.setState({count1:this.count1+1})//第2個計數器用函數參數執行三次+1this.setState(preState=>({count2:preState.count2+1}))this.setState(preState=>({count2:preState.count2+1}))this.setState(preState=>({count2:preState.count2+1}))}render(){return(<div><div>count1:{this.state.count1}</div><div>count2:{this.state.count2}</div><button onClick={this.handleClick}>+1</button></div>)}
}
export default App
  • 運行
    在這里插入圖片描述

  • 初始值都是0沒問題

  • 然后點按鈕
    在這里插入圖片描述

  • 會發現count1只+1,而count2+3,這是因為setState在參數為對象的模式下,對批量操作會進行覆蓋,只取最后一次結果執行

  • setState還有第二個參數,callback,我們在下面講

2.2 setState同步異步問題

2.2.1 setState異步更新

  • 先直接上代碼
import React from 'react'
class App extends React.Component{constructor(props){super(props)this.state={count:0}}handleClick=()=>{this.setState(preState=>({count:preState.count+1}))console.log(this.state.count)}render(){return(<div><div>{this.state.count}</div><button onClick={this.handleClick}>+1</button></div>)}
}
export default App
  • 運行,處置為.,然后點擊+1按鈕,發現頁面顯示1,但是console.log打印0
    在這里插入圖片描述

  • 這是為什么呢,這是因為React在合成事件中,state是異步更新的

  • 為什么會是一步的呢,問題就出現在合成事件上,不懂合成事件的看這篇文章一文講清楚React合成事件機制和this的綁定問題

  • 因為合成事件的原因,console.log的執行時機別state更新的時機要早,所以造成了異步現象

  • 同理,在生命周期函數中改變狀態也會造成異步更新

  • 如果想要拿到更新后的state,就需要setState第二個參數callback,他會在UI更新后被調用

  • 我們這么改一下代碼

import React from 'react'
class App extends React.Component{constructor(props){super(props)this.state={count:0}}handleClick=()=>{this.setState(preState=>({count:preState.count+1}),()=>{console.log(this.state.count)})}render(){return(<div><div>{this.state.count}</div><button onClick={this.handleClick}>+1</button></div>)}
}
export default App
  • 這時候我們拿到了同步的值
    在這里插入圖片描述

2.2.2 setState同步更新

  • 上面說因合成事件會導致異步更新,那如果我們使用原生事件呢,上代碼
import React from 'react'
class App extends React.Component{constructor(props){super(props)this.state={count:0}}componentDidMount(){document.getElementById('update').addEventListener('click',this.handleClick)}handleClick=()=>{this.setState(preState=>({count:preState.count+1}))console.log(this.state.count)}render(){return(<div><div>{this.state.count}</div><button id="update">+1</button></div>)}
}
export default App
  • 運行會發現,還是打印0,哈哈哈,那是因為React在V16版本前,在原生事件和setTimeout中setState是同步事件,這里本來想演示這個來著,但是奈何坐著的React的版本比較高,這里建議大家切換低版本自己運行一下,代碼肯定是沒有任何問題的
  • React為了讓setState在所有場景下保持一致性,從V16+開始,無論是合成事件、原生事件還是setTimeout都是保持異步,要獲取更新后的狀態請統一使用setState第二個回調函數

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/87692.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/87692.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/87692.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

01_軟件卓越之道:功能性與需求滿足

引言 在軟件的世界里&#xff0c;功能性是產品與用戶之間的第一橋梁。一個軟件即使擁有華麗的界面和極致的性能&#xff0c;如果不能解決用戶的核心需求&#xff0c;也終將被市場淘汰。本文將深入探討如何確保軟件的功能性與用戶需求完美契合。 1. 需求理解&#xff1a;從模糊…

StarRocks × Tableau 連接器完整使用指南 | 高效數據分析從連接開始

一、導語&#xff1a;為什么選擇 StarRocks Tableau 連接器&#xff1f; 在當今數據驅動的商業環境中&#xff0c;企業不僅需要一個能夠處理海量數據的高性能分析數據庫&#xff0c;還需要一個直觀、強大的可視化工具來解讀數據背后的故事。StarRocks 作為新一代極速全場景 MP…

基于 SpringBoot+VueJS 助農生鮮銷售系統設計與實現7000字論文實現

摘要本論文設計并實現了一個基于 SpringBoot 和 VueJS 的助農生鮮銷售系統。系統采用前后端分離架構&#xff0c;前端使用 VueJS 框架實現用戶界面&#xff0c;后端使用 SpringBoot 框架構建服務&#xff0c;通過 MyBatis 實現數據持久化。系統實現了農產品展示、在線購物、訂單…

Pytest 測試發現機制詳解:自動識別測試函數與模塊

概述 在編寫自動化測試時,如何讓 Pytest 自動找到你的測試代碼 是一個非常基礎但重要的問題。Pytest 通過其強大的 測試發現(Test Discovery)機制,能夠自動掃描項目目錄、識別測試模塊和測試函數,從而大大簡化了測試流程。 本文將為你詳細講解 Pytest 的測試發現機制,包…

MySQL 時間日期函數

時間日期類型 MySQL中主要支持以下幾種時間日期類型&#xff1a; DATE - 日期類型 格式&#xff1a;YYYY-MM-DD范圍&#xff1a;1000-01-01 到 9999-12-31示例&#xff1a;2023-05-20 TIME - 時間類型 格式&#xff1a;HH:MM:SS范圍&#xff1a;-838:59:59 到 838:59:59示例&…

408第三季part2 - 計算機網絡 - 物理層

理解 這里有8個波形&#xff0c;每個波形代表一個馬原&#xff0c;一個馬原代表多個比特&#xff0c;這里3個比特 求波特率就直接2W 求比特率就要乘log2V 這塊記兩公式就行&#xff0c;一個下面一個上面 題目 4個相位加4種幅度就是有16種波形 這里無噪聲就是奈奎斯特定理 這…

iOS 集成RN Installing glog (0.3.5)報錯的解決方案

在集成執行RN bundle exec pod install 命令到Installing glog (0.3.5)時報錯,報錯信息如下: Installing glog (0.3.5) [!] /bin/bash -c set -e #!/bin/bash # Copyright (c) Facebook, Inc. and its affiliates. # # This source code is licensed under the MIT license …

【進階篇-消息隊列】——MQTT協議如何支持海量的在線IoT設備

目錄 一、什么是IoT二、MQTT 和其他消息隊列的傳輸協議有什么不同三、如何選擇 MQTT 產品四、MQTT 集群如何支持海量在線的 IoT 設備五、總結本文來源:極客時間vip課程筆記 一、什么是IoT IoT,也就是物聯網,物聯網這個詞兒,它的含義還不那么直觀,但你看它的英文:IoT,也就…

Chat Model API

聊天模型API為開發人員提供了將人工智能聊天完成功能集成到應用程序中的能力。它利用預訓練的語言模型&#xff0c;如GPT&#xff08;生成預訓練轉換器&#xff09;&#xff0c;以自然語言對用戶輸入生成類似人類的響應。 API通常通過向人工智能模型發送提示或部分對話來工作&…

【黑群暉】自組硬件/舊電腦nas改造(三)——使用Jellyfin創建家庭影音庫

一、打開套件中心安裝Jellyfin套件 如果找不到Jellyfin套件&#xff0c;需要手動添加三方套件源&#xff1a; 《群暉NAS必學技能&#xff1a;一鍵解鎖三方套件源&#xff0c;PT下載影音播放全搞定&#xff01;》 二、配置Jellyfin 訪問http://群暉IP:8096 進入Jellyfin初始化界…

泰山派編譯debian報錯 lb config: unrecognized option ‘--debootstrap-options‘

簡介 最近在編譯泰山派 編譯buildroot系統正常&#xff0c;但是編譯debian時總是報錯說lb 找不到一些參數&#xff0c;如下圖所示&#xff0c;應該當前的版本較低 不支持這些參數&#xff0c;我試了很多方法 升級次版本 但是提示的是最新的&#xff0c;最后經過一番搜索 在官方…

跨境證券交易系統合規升級白皮書:全鏈路微秒風控+開源替代,護航7月程序化交易新規落地

1 行業變革&#xff1a;四重驅動力重塑證券交易系統 當前全球證券行業正處于深刻變革期&#xff0c;跨境金融活動面臨前所未有的機遇與挑戰。今日央行開展的1310億元7天期逆回購操作&#xff0c;以及國家外匯管理局向合格境內機構投資者(QDII)新增發放30.8億美元投資額度等政策…

Node.js核心API(fs篇)

前言&#xff1a;在Node.js生態系統中&#xff0c;文件系統操作是后端開發不可或缺的一部分。fs模塊作為Node.js核心API的重要組成部分&#xff0c;提供了與文件系統交互的能力&#xff0c;涵蓋了從基礎的文件讀寫到復雜的目錄操作等功能。現代JavaScript開發中&#xff0c;處理…

HarmonyOS學習2---Stage模型

1、工程目錄結構 1.1、入口 UIAbility 1.2、入口page 1.3、配置文件 1、配置文件 1&#xff09;應用級配置文件 --- app.json5 2&#xff09;模塊級配置文件 --- module.json5 3、oh-package.json5 4、資源文件 1&#xff09;element目錄 2&#xff09;media目錄 3&#xff09…

【軟件工程】軟件復刻項目的完整流程指南

軟件復刻項目的完整流程指南 第一章、概述 一、前期準備&#xff1a;明確目標與合規性 1. 法律風險評估 版權排查&#xff1a;確認目標軟件的 UI 設計、代碼、商標是否受保護&#xff08;如界面元素、核心算法是否申請專利&#xff09;。規避侵權&#xff1a;避免直接復制 …

淺談Python 中的當前工作目錄與腳本目錄

Python 中的 os.path.exists() 和 __file__ 使用陷阱&#xff1a;工作目錄 ≠ 腳本目錄 在使用 os.path.exists() 或 open() 等函數操作文件路徑時&#xff0c;筆者常常忽略一個關鍵概念&#xff1a;當前運行目錄&#xff08;Current Working Directory, CWD&#xff09;并不等…

iOS檢測并阻止騷擾電話的方法

檢測并阻止騷擾電話 你可以在 iPhone 上使用“將未知來電者設置為靜音”或第三方 App 來阻止騷擾電話。 打開“將未知來電者設置為靜音” 在 iOS 13 及更高版本中&#xff0c;你可以打開“靜音未知來電”&#xff0c;以免接到陌生人的來電。這一功能可以阻止那些你從未聯系過…

TensorFlow源碼深度閱讀指南

TensorFlow源碼深度閱讀指南 本文基于《TensorFlow內核剖析》附錄A的代碼閱讀方法論&#xff0c;結合實例解析核心源碼閱讀技巧&#xff08;含關鍵圖示&#xff09;&#xff1a;一、源碼閱讀的四個維度 1. 分層切入策略&#xff08;圖A-1&#xff09; #mermaid-svg-ooLMzaWU5ky…

設計模式-責任鏈模式、策略模式

責任鏈模式 Chain of Responsibility&#xff08;職責鏈&#xff09;—對象行為型模式定義&#xff1a;使多個對象都有機會處理請求&#xff0c;從而避免了請求的發送者和接受者之間的耦合關系。將這些對象連成一條鏈&#xff0c;并沿著這條鏈傳遞該請求&#xff0c;直到有對象…

泛微e-cology remarkOperate遠程命令執行漏洞

【高危】泛微e-cology remarkOperate遠程命令執行漏洞 漏洞描述 泛微e-cology是泛微公司開發的協同管理應用平臺。 受影響版本中&#xff0c;接口 /api/workflow/reqform/remarkOperate 存在 SQL 注入漏洞&#xff0c;multipart 類型參數 requestid 直接拼接進 SQL 語句&…