国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

文字

通常,幾個(gè)組件需要反映相同的變化數(shù)據(jù)。我們建議將共享狀態(tài)提升至最接近的共同祖先。讓我們看看這是如何運(yùn)作的。

在本節(jié)中,我們將創(chuàng)建一個(gè)溫度計(jì)算器,用于計(jì)算在給定溫度下水是否沸騰。

我們將從一個(gè)叫做組件開始BoilingVerdict。它接受celsius溫度作為支柱,并打印是否足夠煮沸水:

function BoilingVerdict(props) {  
    if (props.celsius >= 100) {    
        return <p>The water would boil.</p>;  
    }  
    return <p>The water would not boil.</p>;}

接下來,我們將創(chuàng)建一個(gè)名為的組件Calculator。它呈現(xiàn)一個(gè)<input>讓你輸入溫度,并保持其價(jià)值this.state.temperature。

此外,它呈現(xiàn)BoilingVerdict當(dāng)前輸入值。

class Calculator extends React.Component {  
    constructor(props) {    
        super(props);    
        this.handleChange = this.handleChange.bind(this);    
        this.state = {temperature: ''};  }  
        handleChange(e) {    
            this.setState({temperature: e.target.value});  }  
            render() {    
            const temperature = this.state.temperature;    
            return (<fieldset><legend>Enter temperature in Celsius:</legend><input
              value={temperature}
              onChange={this.handleChange} />        <BoilingVerdict
              celsius={parseFloat(temperature)} />      </fieldset>    );  }
              }

添加第二個(gè)輸入

我們的新要求是,除了攝氏溫度輸入外,我們還提供華氏溫度輸入,并且它們保持同步。

我們可以從提取TemperatureInput組件開始Calculator。我們將添加一個(gè)新的scale道具,它可以是"c"或者"f"

const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'};
class TemperatureInput extends React.Component {  
    constructor(props) {    
    super(props);    
    this.handleChange = this.handleChange.bind(this);    
    this.state = {temperature: ''};  
    }  
    handleChange(e) {    
        this.setState({temperature: e.target.value});  
        }  
    render() {       
        const temperature = this.state.temperature;    
        const scale = this.props.scale;    
        return (      <fieldset><legend>Enter temperature in {scaleNames[scale]}:</legend><input value={temperature}
               onChange={this.handleChange} />      </fieldset>    );  
    }
}

我們現(xiàn)在可以改變Calculator以呈現(xiàn)兩個(gè)單獨(dú)的溫度輸入:

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

在 CodePen 上試用它。

我們現(xiàn)在有兩個(gè)輸入,但是當(dāng)你在其中一個(gè)輸入溫度時(shí),另一個(gè)不會(huì)更新。這與我們的要求相矛盾:我們希望保持同步。

我們也無法顯示BoilingVerdictCalculator。在Calculator不知道當(dāng)前的溫度,因?yàn)樗遣卦诶锩娴?code>TemperatureInput。

編寫轉(zhuǎn)換函數(shù)

首先,我們將編寫兩個(gè)函數(shù)將攝氏溫度轉(zhuǎn)換為華氏溫度,然后返回:

function toCelsius(fahrenheit) {  
        return (fahrenheit - 32) * 5 / 9;
    }
function toFahrenheit(celsius) {  
    return (celsius * 9 / 5) + 32;
}

這兩個(gè)函數(shù)轉(zhuǎn)換數(shù)字。我們將編寫另一個(gè)函數(shù),它將字符串temperature和轉(zhuǎn)換器函數(shù)作為參數(shù)并返回一個(gè)字符串。我們將使用它來計(jì)算基于其他輸入的一個(gè)輸入的值。

它會(huì)在無效的情況下返回一個(gè)空字符串temperature,并將輸出保留為小數(shù)點(diǎn)后第三位:

function tryConvert(temperature, convert) {  
    const input = parseFloat(temperature);  
    if (Number.isNaN(input)) {    return '';  }  
    const output = convert(input);  
    const rounded = Math.round(output * 1000) / 1000;  
    return rounded.toString();
    }

例如,tryConvert('abc', toCelsius)返回一個(gè)空字符串,并tryConvert('10.22', toFahrenheit)返回'50.396'。

提升狀態(tài)

目前,這兩個(gè)TemperatureInput組件都獨(dú)立地將其值保持在本地狀態(tài):

class TemperatureInput extends React.Component {  
    constructor(props) {    
    super(props);    
    this.handleChange = this.handleChange.bind(this);    
    this.state = {temperature: ''};  }  
    handleChange(e) {    
        this.setState({temperature: e.target.value});  
        }  
    render() {    const temperature = this.state.temperature;    // ...

但是,我們希望這兩個(gè)輸入互相同步。當(dāng)我們更新攝氏溫度輸入時(shí),華氏溫度輸入應(yīng)反映轉(zhuǎn)換后的溫度,反之亦然。

在 React 中,共享狀態(tài)是通過將它移動(dòng)到需要它的組件的最接近的共同祖先來完成的。這被稱為“提升狀態(tài)”。我們將從當(dāng)?shù)貒抑幸瞥?code>TemperatureInput并將其移入Calculator。

如果Calculator擁有共享狀態(tài),它將成為兩個(gè)輸入中當(dāng)前溫度的“真值源”。它可以指導(dǎo)他們都有相互一致的價(jià)值觀。由于兩個(gè)TemperatureInput組件的道具來自同一個(gè)父Calculator組件,因此兩個(gè)輸入始終保持同步。

讓我們看看這是如何一步一步工作。

首先,我們將替換this.state.temperaturethis.props.temperatureTemperatureInput部件?,F(xiàn)在,讓我們假裝this.props.temperature已經(jīng)存在,盡管我們需要Calculator在未來將它傳遞出去:

  render() {    // Before: const temperature = this.state.temperature;    const temperature = this.props.temperature;    // ...

我們知道道具是只讀的。當(dāng)temperature在當(dāng)?shù)氐臓顟B(tài),TemperatureInput可以打電話this.setState()來改變它。但是,現(xiàn)在temperature來自父母的道具,TemperatureInput它無法控制它。

在 React 中,通常通過將組件“控制”來解決這個(gè)問題。就像 DOM <input>接受a valueonChangeprop一樣,自定義也可以TemperatureInput接受它的父項(xiàng)temperatureonTemperatureChange道具Calculator

現(xiàn)在,當(dāng)TemperatureInput想要更新其溫度時(shí),它會(huì)調(diào)用this.props.onTemperatureChange

  handleChange(e) {    // Before: this.setState({temperature: e.target.value});    this.props.onTemperatureChange(e.target.value);    // ...

注意:對(duì)自定義組件中的任一temperatureonTemperatureChange名稱沒有特殊含義。我們可以稱其他任何東西,比如說它們的名字valueonChange這是一個(gè)通用的慣例。

onTemperatureChange支柱將與一起提供temperature由父支柱Calculator組件。它將通過修改其自身的本地狀態(tài)來處理更改,從而使用新值重新呈現(xiàn)兩個(gè)輸入。我們Calculator很快就會(huì)看到新的實(shí)施。

在深入了解變化之前Calculator,讓我們回顧一下對(duì)TemperatureInput組件的更改。我們已經(jīng)從中刪除了當(dāng)?shù)氐膰遥皇情喿xthis.state.temperature,我們現(xiàn)在閱讀this.props.temperaturethis.setState()我們現(xiàn)在打電話給我們this.props.onTemperatureChange(),而不是打電話給我們,這將由以下人員提供Calculator

class TemperatureInput extends React.Component {  
    constructor(props) {    
        super(props);    
        this.handleChange = this.handleChange.bind(this);  
        }  
    handleChange(e) {    
        this.props.onTemperatureChange(e.target.value);  
        }  
    render() {    
        const temperature = this.props.temperature;    
        const scale = this.props.scale;    
        return (      
            <fieldset>
                <legend>Enter temperature in {scaleNames[scale]}:</legend><input value={temperature}
               onChange={this.handleChange} />      
            </fieldset>    );  
            }
}

現(xiàn)在我們來看看這個(gè)Calculator組件。

我們將存儲(chǔ)當(dāng)前的輸入temperaturescale處于本地狀態(tài)。這是我們從投入中“提起來”的狀態(tài),它將成為兩者的“真相之源”。它是我們?yōu)榱顺尸F(xiàn)兩個(gè)輸入而需要知道的所有數(shù)據(jù)的最小表示。

例如,如果我們?cè)跀z氏度輸入中輸入37,則Calculator組件的狀態(tài)將為:

{
  temperature: '37',
  scale: 'c'}

如果我們稍后編輯華氏場(chǎng)為212,那么Calculator將會(huì)是:

{
  temperature: '212',
  scale: 'f'}

我們可以存儲(chǔ)兩個(gè)輸入的值,但事實(shí)證明這是不必要的。存儲(chǔ)最近更改的輸入的值以及它所表示的比例就足夠了。然后,我們可以基于當(dāng)前temperaturescale單獨(dú)推斷另一個(gè)輸入的值。

輸入保持同步,因?yàn)樗鼈兊闹凳菑南嗤臓顟B(tài)計(jì)算得出的:

class Calculator extends React.Component {  
    constructor(props) {    
        super(props);    
        this.handleCelsiusChange = this.handleCelsiusChange.bind(this);    
        this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);    
        this.state = {temperature: '', scale: 'c'};  }  
        handleCelsiusChange(temperature) {    
            this.setState({scale: 'c', temperature});  }  
            handleFahrenheitChange(temperature) {    
                this.setState({scale: 'f', temperature});  
                }  
            render() {    
                const scale = this.state.scale;    
                const temperature = this.state.temperature;    
                const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;    
                const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;    
                return (      
                    <div><TemperatureInput
                      scale="c"
                      temperature={celsius}
                      onTemperatureChange={this.handleCelsiusChange} />        
                      <TemperatureInput
                      scale="f"
                      temperature={fahrenheit}
                      onTemperatureChange={this.handleFahrenheitChange} />        
                      <BoilingVerdict
                      celsius={parseFloat(celsius)} />      
                      </div>    );  
                      }
}

在 CodePen 上試用它。

現(xiàn)在,無論您編輯哪個(gè)輸入,this.state.temperaturethis.state.scaleCalculator獲取更新。其中一個(gè)輸入按原樣得到值,因此任何用戶輸入都會(huì)保留,而另一個(gè)輸入值總是基于此重新計(jì)算。

讓我們回顧一下編輯輸入時(shí)會(huì)發(fā)生的情況:

  • React 調(diào)用onChange在 DOM 上指定的函數(shù)<input>。在我們的例子中,這是組件中的handleChange方法TemperatureInput。

  • 組件中的handleChange方法使用新的期望值TemperatureInput調(diào)用this.props.onTemperatureChange()。它的道具,其中包括onTemperatureChange,由其母公司提供的Calculator。

  • 當(dāng)它先前渲染中,Calculator已經(jīng)指定onTemperatureChange了攝氏的TemperatureInputCalculatorhandleCelsiusChange方法,以及onTemperatureChange所述華氏TemperatureInputCalculatorhandleFahrenheitChange方法。所以Calculator根據(jù)我們編輯的輸入來調(diào)用這兩個(gè)方法。

  • 在這些方法中,Calculator組件要求 React 通過調(diào)用this.setState()新的輸入值和我們剛剛編輯的輸入的當(dāng)前比例重新呈現(xiàn)自己。

  • React 調(diào)用Calculator組件的render方法來了解 UI 的外觀。根據(jù)當(dāng)前溫度和活動(dòng)比例重新計(jì)算兩個(gè)輸入的值。溫度轉(zhuǎn)換在這里執(zhí)行。

  • React 用它們指定的新道具調(diào)用render各個(gè)TemperatureInput組件的方法Calculator。它了解他們的用戶界面應(yīng)該是什么樣子。

  • React DOM 更新 DOM 以匹配所需的輸入值。我們剛剛編輯的輸入接收其當(dāng)前值,另一個(gè)輸入更新為轉(zhuǎn)換后的溫度。

每次更新都經(jīng)歷相同的步驟,以使輸入保持同步。

得到教訓(xùn)

對(duì)于在 React 應(yīng)用程序中更改的任何數(shù)據(jù),應(yīng)該有一個(gè)“真相源”。通常,首先將狀態(tài)添加到需要渲染的組件中。然后,如果其他組件也需要它,可以將它提升到最接近的共同祖先。與其試圖在不同組件之間同步狀態(tài),您應(yīng)該依賴自頂向下的數(shù)據(jù)流。

提升狀態(tài)涉及編寫比雙向綁定方法更多的“樣板”代碼,但作為一個(gè)好處,查找和隔離錯(cuò)誤需要較少的工作。由于任何狀態(tài)“存在于”某個(gè)組件中,并且該組件本身可以改變它,所以錯(cuò)誤的表面積大大降低。另外,您可以實(shí)現(xiàn)任何自定義邏輯來拒絕或轉(zhuǎn)換用戶輸入。

如果某件事可以從道具或狀態(tài)中推導(dǎo)出來,那么它可能不應(yīng)該處于這個(gè)狀態(tài)。例如,而不是存儲(chǔ)既celsiusValuefahrenheitValue,我們只是存儲(chǔ)上次編輯temperaturescale。其他輸入的值可以始終由render()方法中的值來計(jì)算。這讓我們可以清除或應(yīng)用舍入到其他字段,而不會(huì)丟失用戶輸入的任何精度。

當(dāng)您在 UI 中發(fā)現(xiàn)錯(cuò)誤時(shí),可以使用 React Developer Tools 檢查道具并向上移動(dòng)樹,直到找到負(fù)責(zé)更新狀態(tài)的組件。這可以讓你追蹤錯(cuò)誤來源。

上一篇: 下一篇: