Shared state : state에 있는 데이터를 여러개의 하위 컴포넌트에서 공통적으로 사용하는 경우
각 하위 컴포넌트가 state를 가질 필요 없이 부모 컴포넌트의 state를 가져다 쓰면 된다.
하위 컴포넌트의 state를 공통 상위 컴포넌트로 올리는 행위 (props를 사용하여 상위 컴포넌트의 값을 전달받고, 변경한 값을 상위 컴포넌트에 올려줌)
// TempaeratureInput.jsx
import React from 'react';
const scaleNames = {
c: '섭씨',
f: '화씨',
};
function Temperatureinput(props) {
const handleChange = (event) => {
props.onTemperatureChange(event.target.value);
};
return (
<fieldset>
<legend>
온도를 입력해주새요(단위:{scaleNames[props.scale]})
</legend>
<input value={props.temperature} onChange={handleChange} />
</fieldset>
);
}
export default Temperatureinput
props로 부모의 scale(단위), temperature(온도), onTemperatureChange 함수를 전달 받으며 입력/출력을 담당하는 컴포넌트이다.
(state를 변환해주는 함수인 onTemperatureChange는 부모 컴포넌트에 정의되어있지만, 하위 컴포넌트인 해당 컴포넌트에서 사용(호출)된다)
// Calculator.jsx
import React, { useState } from 'react';
import Temperatureinput from './Temperatureinput';
function BoilingVerdict(props) {
if (props.celsius >= 100) {
return <p>물이 끓습니다.</p>;
};
return <p>물이 끓지 않습니다.</p>;
}
function toCelsius(fahrenheit) {
return ((fahrenheit - 32) *5) / 9;
}
function toFahrenheiht(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, toFahrenheiht) : temperature;
return (
<div>
<Temperatureinput
scale="c"
temperature={celsius}
onTemperatureChange={handleCelsiusChange}
/>
<Temperatureinput
scale="f"
temperature={fahrenheit}
onTemperatureChange={handleFahrenheitChange}
/>
<BoilingVerdict celsius={parseFloat(celsius)} />
</div>
)
}
export default Calculator
scale과 temperature를 state로 관리하고 있으며, scale state에 따라 섭씨는 화씨로, 화씨는 섭씨로 변환하여 하위 컴포넌트로 전달해주고 있다.

참고