React 三大屬性之state的使用詳解
React中很多地方需要用到數(shù)據(jù),這在React中被叫做狀態(tài),我們需要一個專門管理狀態(tài)的方法,于是state相關(guān)的就誕生了。state應(yīng)該被要求有兩個基本功能,一,能夠存儲一定的值,從而能被react使用,二,能夠再它改變的時候被React監(jiān)聽到并且重新渲染。這里分別介紹一下在類和函數(shù)組件中state的寫法:
類組件
class ClassComponent extends React.Component{
constructor(props){
super(props)
} //可寫可不寫
render(){
return (
//這里面可以寫jsx語法
)
}
}
setState我們一般用來改變狀態(tài),在里面可以直接傳一個要改變的對象,也可以傳一個回調(diào)函數(shù),注意,此時如果傳入的是對象的話,React只是做了一層淺拷貝,而不是深拷貝,所以此時如果對象中有其他對象進(jìn)行了改變React無法知道進(jìn)行渲染。這個方法本質(zhì)上是傳入了一個新的值,將原先的值進(jìn)行了覆蓋,如果這個值跟原先的值一樣,那么React就不會進(jìn)行渲染。
React為什么要這么麻煩,不能直接修改值?因?yàn)樵赗eact中,有一個概念叫做可變性。React通過setState中的狀態(tài)的改變知道哪些地方發(fā)生了,于是進(jìn)行渲染,如果直接改變了state,React無法感知到,所以無法渲染。簡單來說,它沒有像vue一樣雙向數(shù)據(jù)綁定。
類組件中的constructor可寫可不寫,寫上這個構(gòu)造函數(shù)的作用主要有兩個:
- 為了給this.state賦值對象來初始化內(nèi)部state的值
constructor(props){
super(props)
this.state = {n:12}
}
render(){
return (
<div>
<h1>THE TIME IS {this.state.n}</h1>
</div>
)
}
注意這里不能寫setState,以上的方法React也可以在外面設(shè)定,即
state = {n:12}
render(){
return (
<div>
<h1>THE TIME IS {this.state.n}</h1>
</div>
)
}
- 為事件處理函數(shù)綁定實(shí)例
constructor(props){
super(props)
this.addNum = function(){fn()}.bind(this)
}
render(){
return (
<button onClick={this.addNum}>+1</button>
)
}
但是這種方法在React中也有新的方法替代了,代碼如下:
addNum = ()=>{
fn()
}
render(){
return (
<button onClick={this.addNum}>+1</button>
)
}
所以上述的構(gòu)造函數(shù)繼承父類的方法根本沒有必要寫。
函數(shù)組件
import {useState} from "react"
function FunctionComponent(){
const [data,setData] = useState("你要傳入的初始值")
return (
<div>SHOW DATA {state}</div>
)
}
這里的setData的作用跟setState類似,但是它只能用來改變data的狀態(tài),需要改變的時候傳入一個回調(diào)函數(shù)。函數(shù)的參數(shù)是之前的值,返回一個要改變的值。這個方法本質(zhì)是需要傳入一個新的對象,來改變React之前對象的值。 對此還能簡便的直接寫改變的值,默認(rèn)會對應(yīng)到當(dāng)前對象并且改變它的值
以上方法比原先的setState要簡便不少,但是麻煩的是如果有多個數(shù)據(jù),需要多次useState而不能一次性傳入多個值。不過大多數(shù)情況下,數(shù)據(jù)管理的問題都是交給Redux來管理的,所以并不需要React本身來操心
setState的坑
在改變React組件狀態(tài)的時候,經(jīng)常遇到的問題是setState的值合并??慈缦聠栴}:
this.addNum = function () {
this.setState({num:this.state.num+1})
this.setState({num:this.state.num+1})
this.setState({num:this.state.num+1})
}.bind(this)
此時當(dāng)addNum函數(shù)被觸發(fā)的時候,num只加了1。并沒有像我們想象的加了3。 對此,React本身的解釋是
調(diào)用 setState 其實(shí)是異步的 —— 不要指望在調(diào)用 setState 之后,this.state 會立即映射為新的值
對此的解釋是:
- 無論調(diào)用多少次setState,都不會立即執(zhí)行更新。而是將要更新的state存入'_pendingStateQuene',將要更新的組件存入'dirtyComponent';
- 當(dāng)根組件didMount后,批處理機(jī)制更新為false。此時再取出'_pendingStateQuene'和'dirtyComponent'中的state和組件進(jìn)行合并更新;
簡單來說,就是React執(zhí)行時,為了提高性能,會把要更新的setState存入一個數(shù)組,當(dāng)React本身的同步代碼執(zhí)行完畢,更新之前,將數(shù)組中的setState取出,然后進(jìn)去渲染。上述代碼中,我們因?yàn)閷⑼酱athis.setState({num:this.state.num+1})加入了setState中,所以在批處理取出的時候,會產(chǎn)生合并,將眾多的setState合并為一句話,從而只改變了1。因?yàn)檫@個機(jī)制,所以讓setState像異步代碼,但是其實(shí)它是同步執(zhí)行的,此時我們?nèi)绻麑⒅暗耐酱a改成異步的,我們就得到了我們想要的結(jié)果
this.addNum = function () {
setTimeout(()=>{ this.setState({num:this.state.num+1}) },0)
setTimeout(()=>{ this.setState({num:this.state.num+1}) },0)
setTimeout(()=>{ this.setState({num:this.state.num+1}) },0)
}.bind(this)
此時,值直接就加了3,因?yàn)楫惒酱a會在代碼執(zhí)行的時候暫存。在所有同步代碼執(zhí)行完畢的時候再執(zhí)行,此時批處理機(jī)制已經(jīng)結(jié)束了,于是三個函數(shù)都被執(zhí)行了,于是加了3 這是目前為止能想到的,如果以后有新的還會增加
以上就是React 三大屬性之state的使用詳解的詳細(xì)內(nèi)容,更多關(guān)于React 三大屬性之state的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React實(shí)現(xiàn)前端選區(qū)的示例代碼
本文主要介紹了React實(shí)現(xiàn)前端選區(qū)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
在React中實(shí)現(xiàn)子組件向父組件傳值的幾種方法
在React應(yīng)用中,組件間的通信是常見的需求,通常,父組件通過props向子組件傳遞數(shù)據(jù),但有時也需要子組件向父組件傳遞數(shù)據(jù),本文將探討如何在React中實(shí)現(xiàn)子組件向父組件傳值的幾種方法,需要的朋友可以參考下2025-04-04
React中hook函數(shù)與useState及useEffect的使用
這篇文章主要介紹了React中hook函數(shù)與useState及useEffect的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10
React?Server?Component混合式渲染問題詳解
React?官方對?Server?Comopnent?是這樣介紹的:?zero-bundle-size?React?Server?Components,這篇文章主要介紹了React?Server?Component:?混合式渲染,需要的朋友可以參考下2022-12-12

