Shared State

: 하위 컴포넌트가 부모 컴포넌트의 state를 공유하여 사용하는 것

function Calculator(props) {
  return (
    <div>
      <TemperatureInput scale="c" />
      <TemperatureInput scale="f" />
    </div>
  )
}
const scaleNames = {
  c: '섭씨',
  f: '화씨'
}
function TemperatureInput(props) {
  const [temperature, setTemperature] = useState('');

  const handleChange = (event) => {
    setTemperature(event.target.value);
  }
  
  return (
    <fieldset>
      <legend>섭씨 온도를 입력하세요: {scaleNames[props.scale]}</legend>
      <input type="text" value={temperature} onChange={handleChange} />
    </fieldset>
  )
}

그런데 화씨, 섭씨 입력창에 둘중에 하나의 값이 입력이 되면 남은 하나도 측정치에 맞게 변환이 되게 만들고 싶음

그렇게 하려면 공통으로 가져다가 써야하는게 필요해서 공통으로 쓸 부분은 부모로 끌어올림

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

tryConvert('abc', toCelcius);
tryConvert('10.22', toFahrenheit);

Lifting Shared State

: 하위 컴포넌트의 state를 공통 상위 컴포넌트로 올림!

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

function Calculator(props) {
	const [temperature, setTemperature] = useState('');
	const [scale, setScale] = useState('c');

	const handleCelsiusChange = (temperature) => {
		setTemperature(temperature);
		setScale('c');
	}

	const handleFahrenheitChange = (temperature) => {
		setTemperature(temperature);
		setScale('f');
	}

	const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
	const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
  return (
    <div>
      <TemperatureInput 
				scale="c"
				temperature={celsius}
				onTemperatureChange={handleCelsiusChange}
			 />
      <TemperatureInput 
				scale="f"
				temperature={fahrenheit}
				onTemperatureChange={handleFahrenheitChange}
			 />
			<BoilingVerdict 
				celsius={parseFloat(celsius)}
			/>
    </div>
  )
}
function TemperatureInput(props) {

  const handleChange = (event) => {
    props.setTemperature(event.target.value);
  }
  
  return (
    <fieldset>
      <legend>섭씨 온도를 입력하세요: {scaleNames[props.scale]}</legend>
      <input type="text" value={props.temperature} onChange={handleChange} />
    </fieldset>
  )
}