React狀態(tài)提升案例介紹
1.介紹
所謂 狀態(tài)提升 就是將各個(gè)子組件的 公共state 提升到它們的父組件進(jìn)行統(tǒng)一存儲(chǔ)、處理(這就是所謂的”單一數(shù)據(jù)源“),負(fù)責(zé)setState
的函數(shù)傳到下邊的子級(jí)組件,然后再將父組件處理后的數(shù)據(jù)或函數(shù)props到各子組件中。
那么如果子組件 要 修改父組件的state該怎么辦呢?我們的做法就是 將父組件中負(fù)責(zé)setState的函數(shù),以props的形式傳給子組件,然后子組件在需要改變state時(shí)調(diào)用即可。
實(shí)現(xiàn)方式
實(shí)現(xiàn)方式是 利用最近的共同的父級(jí)組件中,用props的方式傳過(guò)去到兩個(gè)子組件,props中傳的是一個(gè)setState的方法,通過(guò)子組件觸發(fā)props傳過(guò)去的方法,進(jìn)而調(diào)用父級(jí)組件的setState的方法,改變了父級(jí)組件的state,調(diào)用父級(jí)組件的render方法,進(jìn)而同時(shí)改變了兩個(gè)子級(jí)組件的render。
這是 兩個(gè)有關(guān)連的同級(jí)組件的傳值,因?yàn)閞eact的單項(xiàng)數(shù)據(jù)流,所以不在兩個(gè)組件中進(jìn)行傳值,而是提升到 最近的共同的父級(jí)組件中,改變父級(jí)的state,進(jìn)而影響了兩個(gè)子級(jí)組件的render。
官網(wǎng)介紹
通常,多個(gè)組件需要反映相同的變化數(shù)據(jù),這時(shí)我們建議將共享狀態(tài)提升到最近的共同父組件中去。
2.案例
先寫(xiě)一個(gè)溫度輸入組件:
class TemperatureInput extends React.Component { state = { temperature: '' }; handleChange = (e) => { this.setState({ temperature : e.target.value }) }; render() { return ( <fieldset> <legend>輸入{scaleNames[this.props.scale]}:</legend> <input type="number" value={this.state.temperature} onChange={this.handleChange} </fieldset> ) } }
這個(gè)組件就是一個(gè)普通的受控組件,有state
和props
以及處理函數(shù)。
我們?cè)趯?xiě)另一個(gè)組件:
class Calculator extends React.Component { render () { return ( <div> <TemperatureInput scale='c'/> <TemperatureInput scale='f'/> </div> ) } }
這個(gè)組件現(xiàn)在沒(méi)有什么存在的價(jià)值,我們僅僅是給兩個(gè)溫度輸入組件提供一個(gè)父組件,以便我們進(jìn)行后續(xù)的狀態(tài)提升。
現(xiàn)在我們看看網(wǎng)頁(yè)的樣子:
我們可以輸入攝氏度和華氏度,但是我們現(xiàn)在想要讓這兩個(gè)溫度保持一致,就是我們?nèi)绻斎霐z氏度,那么下面的華氏度可以自動(dòng)算出來(lái),如果我們輸入華氏度,那么攝氏度就可以自動(dòng)算出來(lái)。
那么我們按照現(xiàn)在這種結(jié)構(gòu)的話,是非常難以實(shí)現(xiàn)的,因?yàn)槲覀冎肋@兩個(gè)組件之間沒(méi)有任何關(guān)系,它們之間是不知道對(duì)方的存在,所以我們需要把它們的狀態(tài)進(jìn)行提升,提升到它們的父組件當(dāng)中。
那我們看看如何做修改,首先把子組件(溫度輸入組件)的狀態(tài)(state)全部刪除,看看是什么樣子:
class TemperatureInput extends React.Component { handleChange = (e) => { }; render() { return ( <fieldset> <legend>輸入{scaleNames[this.props.scale]}:</legend> <input type="number" value={this.props.temperature} onChange={this.handleChange}/> </fieldset> ) } }
可以看到所有與state
有關(guān)的東西全部刪掉了,然后input
的value
也變成了props
,通過(guò)父組件傳入。那么現(xiàn)在這個(gè)溫度輸入組件其實(shí)就是一個(gè)受控組件了,仔細(xì)回憶一下我們之前講的受控組件,看看是不是這樣意思?
我們通常會(huì)在受控組件發(fā)生改變的時(shí)候傳入一個(gè)onChange
函數(shù)來(lái)改變受控組件的狀態(tài),那么我們這里也是一樣,我們通過(guò)給 溫度輸入組件 傳入某個(gè)函數(shù)來(lái)讓 溫度輸入組件 中的input
發(fā)生變化的時(shí)候調(diào)用,當(dāng)然這個(gè)函數(shù)我們可以隨意命名,假如我們這里叫做onTemperatureChange
函數(shù),那么我們繼續(xù)修改子組件:
class TemperatureInput extends React.Component { handleChange = (e) => { this.props.onTemperatureChange(e.target.value); }; render() { return ( <fieldset> <legend>輸入{scaleNames[this.props.scale]}:</legend> <input type="number" value={this.props.temperature} onChange={this.handleChange}/> </fieldset> ) } }
好了,我們的子組件差不多就是這樣了,當(dāng)然我們可以省略那個(gè)handleChange
函數(shù),因?yàn)榭梢钥吹竭@個(gè)函數(shù)就是調(diào)用了一下那個(gè)props
里的函數(shù),所以我們完全把input
的onChange
這么寫(xiě) <input type="number" value={this.props.temperature} onChange={this.props.onTemperatureChange}/>
這么寫(xiě)的話注意onTemperatrueChange
函數(shù)的參數(shù)是那個(gè)事件,而不是我這里寫(xiě)的e.target.value
。
再看看我們的父組件如何修改,我們首先補(bǔ)上state
,以及子組件對(duì)應(yīng)的onChange
處理方法,以及子組件的值。寫(xiě)好之后大概是這個(gè)樣子:
class Calculator extends React.Component { state = { celsius: '', fahrenheit: '' }; onCelsiusChange = (value) => { this.setState({ celsius: value, fahrenheit: tryConvert(value, toFahrenheit) }); }; onFahrenheitChange = (value) => { this.setState({ celsius: tryConvert(value, toCelsius), fahrenheit: value }); }; render() { return ( <div> <TemperatureInput scale='c' temperature={this.state.celsius} onTemperatureChange={this.onCelsiusChange}/> <TemperatureInput scale='f' temperature={this.state.fahrenheit} onTemperatureChange={this.onFahrenheitChange}/> </div> ) } }
這里我們省略的攝氏度與華氏度的轉(zhuǎn)換函數(shù),比較簡(jiǎn)單,大家自行搜索方法。
到此這篇關(guān)于React狀態(tài)提升案例介紹的文章就介紹到這了,更多相關(guān)React狀態(tài)提升內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React中的useState和setState的執(zhí)行機(jī)制詳解
這篇文章主要介紹了React中的useState和setState的執(zhí)行機(jī)制,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03React項(xiàng)目中axios的封裝與API接口的管理詳解
Axios是一個(gè)npm軟件包,允許應(yīng)用程序?qū)TTP請(qǐng)求發(fā)送到Web API,下面這篇文章主要給大家介紹了關(guān)于React項(xiàng)目中axios的封裝與API接口的管理的相關(guān)資料,需要的朋友可以參考下2021-09-09create-react-app項(xiàng)目配置全解析
這篇文章主要為大家介紹了create-react-app項(xiàng)目配置全解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06React獲取Java后臺(tái)文件流并下載Excel文件流程解析
這篇文章主要介紹了React獲取Java后臺(tái)文件流下載Excel文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06React找不到模塊“./index.module.scss”或其相應(yīng)的類(lèi)型聲明及解決方法
這篇文章主要介紹了React找不到模塊“./index.module.scss”或其相應(yīng)的類(lèi)型聲明及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09React如何通過(guò)@craco/craco代理接口
這篇文章主要介紹了React如何通過(guò)@craco/craco代理接口問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10