網站首頁 編程語言 正文
一、概念與基本使用
props中的所有屬性都是不可變的,這使得React組件不能隨著props的改變而改變。但在實際的開發中,我們更希望的是數據發生變化時,頁面也會隨著數據一起變化。React為我們提供了state用來解決這個問題。
state和props類似,都是一種存儲屬性的方式,但是不同點在于state只屬于當前組件,其他組件無法訪問。并且state是可變的,當其發生變化后組件會自動重新渲染,以使變化在頁面中呈現。
在React中,當組件渲染完畢后,再修改組件中的變量,不會使組件重新渲染。
要使得組件可以收到變量的影響,必須在變量修改后對組件進行重新渲染。
這里我們就需要一個特殊變量,當這個變量被修改時,組件會自動重新渲染。
state相當于一個變量,
只是這個變量在React中進行了注冊,
React會監控這個變量的變化,當state發生變化時,會自動觸發組件的重新渲染
使得我們的修改可以在頁面中呈現出來。
在函數組件中,我們需要通過鉤子函數,獲取state。
使用鉤子 useState()
來創建state。
import {useState} from "react";
它需要一個值作為參數,這個值就是state的初始值
該函數會返回一個數組
- 數組中第一個元素,是初始值
- 初始值只用來顯示數據,直接修改不會觸發組件的重新渲染數組中的第二個元素,是一個函數,通常會命名為setXxx
- 這個函數用來修改state,調用其修改state后會觸發組件的重新渲染,并且使用函數中的值作為新的state值
現有如下組件Clock:
現在我們希望點擊按鈕以后,時間可以刷新直接顯示一個當前的最新日期。希望頁面重新渲染。但是,如果直接在clickHandler中修改date的值是無效的,像這樣:
在函數中使用state我們需要使用一種鉤子(hook)函數。鉤子函數可以在函數組件中“勾出”React的特性,換句話說我們要用一個函數“勾出”state。
語法:
const [state, setState] = useState(initialState);
通過鉤子函數useState()勾出state,useState()中需要傳遞一個初始值,這個值就是你希望在變量中存儲的值。
函數會返回一個數組,數組中有兩個元素,第一個元素是存儲了值的變量,第二個元素是一個函數用來對值進行修改。
比如上邊的案例,可以這樣修改:
使用useState()“勾出”的變量就是一個普通變量,它里邊存儲了初始化的值,這個變量和其他變量沒什么大區別,同樣修改這個變量的值也不會對組件產生實質性的影響,所以不要嘗試直接為state賦值。useState()“勾出”的函數用來修改state的值,他需要一個新的state值作為參數,調用后會觸發組件的重新渲染,從而使得頁面刷新,在每次的重新渲染中都會使用新的state值作為參數。
二、注意問題
引出問題
有了state,使得React組件可以隨著某個值的改變而改變,我們無需再在某個值發生變化后重新手動對界面進行構建,React會替我們完成這些工作,大大降低了我們開發的難度。
但是state中還隱藏著一些不太容易發現的問題,現在假設我們需要開發一個計數器組件,這個組件非常簡單,有一個按鈕和一個數字,每點擊一次按鈕數字就會增加1,大概長成這個樣子:
點擊按鈕以后,數字就會增加1,這個組件的實現很簡單:
Counter.js
在clickHandler()中,我們調用了setCount(count+1)來對count進行更新,每次更新都是在前一次值的基礎上增加1。這個代碼這么寫在大部分的場景下都不會帶來任何的問題,但是在某些情況下就不一定了。
產生問題的原因
在React中我們通過setState()修改狀態都是異步完成的,換句話說并不是調用完setState()后狀態立刻就發生變化,而是需要等上一段時間,當然這段時間不會很長。
像上邊的案例中state的修改雖然是異步完成的,但是由于功能比較簡單,等待時間幾乎可以忽略不計。但隨著功能復雜度的提升,這個間隔會逐漸增多。
問題演示
假設調用setState()后1秒state的值才會真的改變,這時如果我們連續點擊按鈕2次,第1次點擊按鈕時count值是1,第2次點擊速度比較快,從而兩次間隔沒有超過1秒,此時的count值依然是1,這就導致我點擊了兩次按鈕,但是值只增加了1次,因為兩次count+1中的count都是1。
為了演示問題,可以將上述案例的setCount()放入到一個延時調用中:
這樣一來,點擊按鈕后1秒setCount()才會調用,如果我們在1秒內點擊按鈕多次,你會發現按鈕數值只會增加一次,很顯然我們不希望這種情況出現。
解決問題
要解決這個問題,其實也不難,在setState()時除了直接傳遞一個指定值以外,React還允許我們通過一個回調函數來修改state,回調函數的返回值就是新的state的值,使用回調函數的好處是,這個回調函數會確保上一次的setState()調用完成后才被調用,同時會使用最新的state值作為回調函數的第一個參數。這樣一來就有效的避免了無法正確獲取上一個state值的問題。
上邊案例中的 setCount(count+1);
可以改成這個樣子:
setCount(prevState => prevState+1);
這樣一來,函數中的prevState總是上次修改后的最新state,避免再次出現點擊多次按鈕只修改一次的問題。總的來說,當我們修改一個state的值而需要依賴于前邊的值進行計算時,最安全的方式就是通過回調函數而不是直接修改。
原文鏈接:https://blog.csdn.net/qq_43472877/article/details/128283907
相關推薦
- 2022-06-16 Go基礎教程系列之回調函數和閉包詳解_Golang
- 2023-01-02 如何用C#找出數組中只出現了一次的數字_C#教程
- 2022-12-10 Android入門之計時器Chronometer的使用教程_Android
- 2022-07-07 ASP.NET對Cookie的操作_ASP.NET
- 2022-11-14 C語言?ffmpeg與sdl實現播放視頻同時同步時鐘詳解_C 語言
- 2023-02-09 Flask如何接收前端ajax傳來的表單(包含文件)_python
- 2022-10-14 nginx 反向代理以及 location /admin/
- 2022-11-14 基于統計自適應線性回歸-目標尺寸預測
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支