react 수업
12. lifting state up
gongmille
2024. 9. 7. 14:12
여러개의 컴포넌트에서 한 state를 공유 하는 것
-shared state
하위 컴포넌트가 공통된 부모 컴포넌트의 state를 공유하여 사용하는 것
function BoilingVerdict(props){
if(props.celsius >= 100){
return <p>물이 끓습니다.</p>
}
return <p>물이 끓지 않습니다.</p>
}
예시 - 자식 컴포넌트
function Calculator(props){
const [temperature, setTemperature] = useSate('');
const handleChange = (event) => {
setTemperature(event.target.value);
}
return(
<fieldset>
<legend>섭씨 온도를 입력하세요 :</legend>
<input value={temperature} onChange={handleChange} />
<BoilingVerdict celsius={parseFloat(temperature)} />
</fieldset>
);
}
예시 - 부모 컴포넌트
다만 이 경우 온도만 입력하므로 섭씨와 화씨 단위로 입력 받을 수 있게 수정하면 다음과 같다.
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 value={temperature} onChange={handleChange} />
</fieldset>
);
}
function Calculator(props){
return(
<div>
<TemperatureInput scale="c" />
<TemperatureInput scale="f" />
</duv>
);
}
예시 - 입력값 동기화 전
function BoilingVerdict(props){
if(props.celsius >= 100){
return <p>물이 끓습니다.</p>
}
return <p>물이 끓지 않습니다.</p>
}
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(seleuius)} />
</div>
);
}
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>
);
}
예시 - 동기화 처리
-실습
위의 예제를 실제로 실행해보자
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;
TemperatureInput.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 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>
);
}
export default Calculator;
Calculator.jsx
(index.js 생략)
값을 입력하면 다른 빈 칸도 같이 변환되서 입력되는 걸 확인할 수 있다.
이 부분은 좀 난해한 느낌인지라 프로젝트를 하면서 알아가는 수 밖에 없을 것 같다.