종종 동일한 데이터에 대한 변경사항을 여러 컴포넌트에 반영해야 할 필요가 있다. 이럴 때는 가장 가까운 공통 조상으로 state를 끌어올리는 것이 좋다. 어떻게 할 수 있을지 살펴본다.

이번 섹션에서는 주어진 온도에서 물의 끓는 여부를 추정하는 온도 계산기를 만든다.

먼저 BoilingVerdict라는 이름의 컴포넌트부터 만들자. 이 컴포넌트는 섭씨온도를 의미하는 celsius prop을 받아서 이 온도가 물이 끓기에 충분한지 여부를 출력한다.

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

다음으로 Calculator라는 컴포넌트를 만든다. 이 컴포넌트는 온도를 입력할 수 있는 <input>을 렌더링하고 this.state.temperature에 저장한다.

또한 현재 입력값이 대한 BoilingVerdict 컴포넌트를 렌더링한다.

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

두 번째 Input 추가하기

새 요구사항으로써 섭씨 입력 필드뿐만 아니라 화씨 입력 필드를 추가하고 두 필드 간에 동기화 상태를 유지하도록 해본다.

Calculator에서 TemperatureInput 컴포넌트를 빼내는 작업부터 시작해보자. 또한 "c" 또는 "f"의 값을 가질 수 있는 scale prop를 추가할 것이다.

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

이제 Calculator가 분리된 두 개의 온도 입력 필드를 렌더링하도록 변경할 수 있다.

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

이제 두 개의 입력 필드를 갖게 되었다. 그러나 둘 중 하나에 온도를 입력하더라도 다른 하나는 갱신 되지 않는 문제가 있다. 이 것은 두 입력 필드 간에 동기화 상태를 유지하고자 했던 원래 요구사항과는 맞지 않는다.