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에 따라 섭씨는 화씨로, 화씨는 섭씨로 변환하여 하위 컴포넌트로 전달해주고 있다.
참고