首页 > 专栏 > 前端 > 文章详情
React 官网学习 - 组件的状态提升 发布于:2021-03-20 20:25:51   来源:React   查看:7  讨论:0
const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'
};
function toCelsius(fahrenheit) {  //转为摄氏度
  return (fahrenheit - 32) * 5 / 9;
}
function toFahrenheit(celsius) {  //转为华氏度
  return (celsius * 9 / 5) + 32;
}
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();
}
// 父组件
class Calculator extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      temperature: '',
      scale: ''
    };
    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;
    //  如果输入框是f,那么c框得到转换后的值;否则如果输入框是c,那么值就是 输入多少就是多少。
    //  第二条逻辑相同。
    const temperatureC = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
    const temperatureF = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
    return (
        <div>
          {/*通过父组件Calculator,将temperatur传入*/}
          <TemperatureInput
              scale="c"
              temperature={temperatureC}
              onTemperatureChange={this.handleCelsiusChange} />
          <TemperatureInput
              scale="f"
              temperature={temperatureF}
              onTemperatureChange={this.handleFahrenheitChange} />
        </div>
    );
  }
};

//在React中,将多个组件中需要共享的state向上移动到它们最近的父组件中,便可实现state共享。
class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    //Before this.state = {temperature: ''};// 温度数值已经变为从父组件传递,这里就不用初始化了
  }
  handleChange(e) {
    // Before: this.setState({temperature: e.target.value});
    this.props.onTemperatureChange(e.target.value);   //数据来源父组件的props
  }
  render() {
    //这里我们把this.state.temperature 改为 this.props.temperature ,数据来自外部
    // Before: const temperature = this.state.temperature;
    const temperature = this.props.temperature;
    const scale = this.props.scale;
    //我们知道,props是只读的。当temperature存在于TemperatureInput组件的state中时,组件调用
    //this.setState()便可修改它。然而,temperature是由父组件传入的prop,
    //TemperatureInput 组件便失去了对它的控制权。
    //使用 “受控组件”去解决。与DOM中的<input>接收value和onChange一样,自定义的TemperatureInput组件
    //接受temperature和onTemperatureChange这两个来自父组件Calculator的props。
    //现在,当TemperatureInput组件想更新温度时,需调用this.props.onTemperatureChange来更新它:
    return (
        <fieldset>
          <legend>Enter temperature in {scaleNames[scale]}:</legend>
          <input value={temperature}
                 onChange={this.handleChange} />
        </fieldset>
    );
  }
}
ReactDOM.render(<Calculator />, document.getElementById('root'));

评论

  • 匿名