[React] Lifting State Up

J.·2024년 5월 22일

React

목록 보기
8/11
post-thumbnail

🔍 한눈에 알아보기

Lifting State Up

  • 하위 component의 state를 공통 상위 component로 올림
  • 여러개의 component에서 state를 공유

Shared State

  • State에 있는 데이터를 여러 개의 하위 component에서 공통적으로 사용
  • 공통된 부모 component의 state를 사용

⌨️ 코드로 알아보기

온도를 섭씨 또는 화씨로 입력 받아 끓는지 안 끓는지가 출력되는 코드를 살펴보자.

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();
}
profile
코린이 (코인 어린이 아니라 코딩 어린이임)

0개의 댓글