10. react - 状态提升


1. 什么是状态提升:

  状态提升是指,公共父组件统一管理子组件状态的过程。

2. 为什么要做状态提升:

  当两个子组件渲染同一个数据的不同状态时,并且要求两个子组件数据同步变化,子组件之间不能相互作用,这时,就需要提升到公共父组件处理要渲染的数据。

  例如:官网 摄氏度和华氏度控制水沸腾的例子

3. 数据流向:

  状态管理组件(父组件) 通过 【属性绑定】 状态 和 改变状态的方法

  子组件通过 props 获取数据和父组件的方法,通过 this.props 渲染数据,调用方法。

/*数据处理的公共方法*/
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();
}
const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'
};

// 1. 抽离温度显示组件
class TemperatureInput extends React.Component{
  constructor (props) {
    super(props)
    
    this.handleChangeT = this.handleChangeT.bind(this)

    this.inputRef = React.createRef()
  }

  // 通过事件触发父组件的方法
  handleChangeT (e) {
    console.log(this.inputRef)
    // 通过props触发父组件的方法
    this.props.onTemperatureChange(this.inputRef.current.value)
  }

  render () {
    const temperature = this.props.temperature
    return (
      
{this.props.type === 'c' ? 请输入摄氏度 : 请输入华氏度} this.handleChangeT} ref={this.inputRef} />
) } } // 抽取 Calculator 组件, 管理状态 class Calculator extends React.Component { constructor (props) { super(props) this.state = { temperature: '', type: 'c' } this.calcC = this.calcC.bind(this) this.calcF = this.calcF.bind(this) } calcC (temperature) { this.setState({ temperature, type: 'c' }) } calcF (temperature) { this.setState({ temperature, type: 'f' }) } render() { // 计算摄氏度,华氏度 fahrenheit const temperature = this.state.temperature const fahrenheit = this.state.type === 'c' ? tryConvert(temperature, toFahrenheit) : temperature const celsius = this.state.type === 'f' ? tryConvert(temperature, toCelsius) : temperature return (
    // onTemperatureChange属性传递方法给子组件
onTemperatureChange={this.calcC} temperature={celsius} /> onTemperatureChange={this.calcF} temperature={fahrenheit} /> {celsius >= 100 ?

水沸腾了

:

水还没开

}
) } } ReactDOM.render( , document.getElementById('root') )