온도를 섭씨 또는 화씨로 입력 받아 끓는지 안 끓는지가 출력되는 코드를 살펴보자.
function BoilingVerdict(props) {
if(props.celsius >= 100){
return <p>Boiling</p>
}
return <p>Not boiling</p>
}
function TemperatureCalculator(props) {
const [temperature, setTemperature] = useState('');
const handleChange = (event) => {
setTemperature(event.target.value);
}
return(
<fieldset>
<legend>Temperature in celsius: </legend>
<input value={temperature} onChange={handleChange}/>
<BoilingVerdict celsius={parseFloat(temperature)}/>
</fieldset>
)
}
위 코드를 shared state를 이용해 섭씨화 화씨를 받아 변환해 출력하는 코드로 바꿔보자.
const scaleNames={
c: '섭씨',
f: '화씨'
};
function TemperatureInput(props){
const handleChange = (event) => {
props.onTemperatureChange(event.target.value);
}
return (
<fieldset>
<legend>
Temperature(scale: {scaleNames[props.scale]});
</legend>
<input value={props.temperature} onChange={handleChange}/>
</fieldset>
)
}
이제 TemperatureCalculator component를 변경해보자.
function TemperatureCalculator(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, toFehrenheit) : temperature;
return(
<div>
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={handleCelsiusChange}/>
<TemperatureInput
scale="f"
temperature={fahrenheit}
onTemperatureChange={handleFahrenheitChange}/>
<BoilingVerdict celsius={parseFloat(celsius)}/>
</div>
)
}
function toCelsius(fahrenheit){
return (farenheit - 32) * 5 / 9;
}
function toFarenheit(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();
}