react 狀態(tài)提升

狀態(tài)提升是什么意思? 一個最簡單的例子,就是如果兩個子組件需要利用到對方的狀態(tài)的話,那么這個時候我們就需要使用到狀態(tài)提升,具體的做法就是把兩個子組件的狀態(tài)寫到它們的父組件當(dāng)中,然后父組件把狀態(tài)傳遞到子組件的props中去,這樣子組件也相當(dāng)于有狀態(tài)。父組件相當(dāng)于是數(shù)據(jù)源,這樣的話,子組件是沒有控制權(quán)的,那么如果之前子組件的state是受到控制的怎么辦呢?就像我們之前說到的受控組件一樣,像:

<input value = {this.state.value} onChange = {this.handleChange}/>

那我們就得在父組件中寫出子組件的處理函數(shù),并在處理函數(shù)中更改父組件的state

來看一個完整的狀態(tài)提升的例子:

先寫一個溫度輸入組件:

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

這個組件就是一個普通的受控組件,有stateprops以及處理函數(shù)。

我們在寫另一個組件:

class Calculator extends React.Component {
    render () {
        return (
            <div>
                <TemperatureInput scale='c'/>
                <TemperatureInput scale='f'/>
            </div>
        )
    }
}

這個組件現(xiàn)在沒有什么存在的價值,我們僅僅是給兩個溫度輸入組件提供一個父組件,以便我們進(jìn)行后續(xù)的狀態(tài)提升。

現(xiàn)在我們看看網(wǎng)頁的樣子:


我們可以輸入攝氏度和華氏度,但是我們現(xiàn)在想要讓這兩個溫度保持一致,就是我們?nèi)绻斎霐z氏度,那么下面的華氏度可以自動算出來,如果我們輸入華氏度,那么攝氏度就可以自動算出來。

那么我們按照現(xiàn)在這種結(jié)構(gòu)的話,是非常難以實(shí)現(xiàn)的,因?yàn)槲覀冎肋@兩個組件之間沒有任何關(guān)系,它們之間是不知道對方的存在,所以我們需要把它們的狀態(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)的東西全部刪掉了,然后inputvalue也變成了props,通過父組件傳入。那么現(xiàn)在這個溫度輸入組件其實(shí)就是一個受控組件了,仔細(xì)回憶一下我們之前講的受控組件,看看是不是這樣意思?

我們通常會在受控組件發(fā)生改變的時候傳入一個onChange函數(shù)來改變受控組件的狀態(tài),那么我們這里也是一樣,我們通過給 溫度輸入組件 傳入某個函數(shù)來讓 溫度輸入組件 中的input發(fā)生變化的時候調(diào)用,當(dāng)然這個函數(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)然我們可以省略那個handleChange函數(shù),因?yàn)榭梢钥吹竭@個函數(shù)就是調(diào)用了一下那個props里的函數(shù),所以我們完全把inputonChange這么寫
<input type="number" value={this.props.temperature} onChange={this.props.onTemperatureChange}/>這么寫的話注意onTemperatrueChange函數(shù)的參數(shù)是那個事件,而不是我這里寫的e.target.value。

再看看我們的父組件如何修改,我們首先補(bǔ)上state,以及子組件對應(yīng)的onChange處理方法,以及子組件的值。寫好之后大概是這個樣子:

    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ù),比較簡單,大家自行搜索方法。

最后加上我們的 水是否能夠燒開的組件。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 狀態(tài)提升 通常情況下,同一個數(shù)據(jù)的變化需要幾個不同的組件來反映。我們建議提升共享的狀態(tài)到它們最近的祖先組件中。我們...
    初漾流影閱讀 723評論 0 0
  • 最近看了一本關(guān)于學(xué)習(xí)方法論的書,強(qiáng)調(diào)了記筆記和堅(jiān)持的重要性。這幾天也剛好在學(xué)習(xí)React,所以我打算每天堅(jiān)持一篇R...
    gaoer1938閱讀 1,819評論 0 5
  • 說在前面 關(guān)于 react 的總結(jié)過去半年就一直碎碎念著要搞起來,各(wo)種(tai)原(lan)因(le)。心...
    陳嘻嘻啊閱讀 7,045評論 7 41
  • 通常,幾個組件需要根據(jù)同一個數(shù)據(jù)變化做出響應(yīng)。我們建議將這個共享的狀態(tài)提升到他們最近的一個共用祖先。讓我們看看實(shí)際...
    莫銘閱讀 961評論 0 1
  • 本筆記基于React官方文檔,當(dāng)前React版本號為15.4.0。 1. 安裝 1.1 嘗試 開始之前可以先去co...
    Awey閱讀 7,936評論 14 128

友情鏈接更多精彩內(nèi)容