RN提升状态

2020-05-03  本文已影响0人  琳媚儿

摄氏温度和华氏温度

可以从中提取一个TemperatureInput组件开始App。我们将scale为其添加一个新的道具,可以是"c"或"f":

//提升状态

const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'
};


更改App来渲染两个单独的温度输入:

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

创建一个温度计算器,计算在给定温度下水是否会沸腾
BoilingVerdict以摄氏度为单位传递温度。

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

编写转换功能

首先,我们将编写两个函数以将摄氏温度转换为华氏度并返回:

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

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

编写另一个函数,该函数将一个字符串temperature和一个转换函数作为参数并返回一个字符串。我们将使用它来基于另一个输入来计算一个输入的值。

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

提升状态

在React中,共享状态是通过将其上移到需要该状态的组件的最接近的公共祖先来完成的。这称为“提升状态”。我们将从中移除本地状态,TemperatureInput然后将其移至App。

如果App拥有共享状态,则它将成为两个输入中当前温度的“真相来源”。它可以指示它们两个具有彼此一致的值。由于两个TemperatureInput组件的道具都来自同一父App组件,因此两个输入将始终保持同步。

自定义组件中的prop名称temperature或onTemperatureChangeprop名称没有特殊含义。我们可以用其他任何名称来称呼它们,例如命名它们value,onChange这是一个常见的约定。

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

fieldset 将表单内的相关元素分组
引用组件 BoilingVerdict,
将输入框中的 temperature 传给BoilingVerdict组件进行celsius比较
总:

class App  extends React.Component {
  constructor(props) {
    super(props);
    this.state = {temperature: '', scale: 'c'};
    this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
    this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
  }
  /* 摄氏温度 */
  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>
      );
  }
}
export default App;
image
上一篇下一篇

猜你喜欢

热点阅读