[React] Lifting State Up

이예지·2023년 10월 1일
0

React Study

목록 보기
9/12
post-custom-banner

💡 Shared State

Shared state : state에 있는 데이터를 여러개의 하위 컴포넌트에서 공통적으로 사용하는 경우각 하위 컴포넌트가 state를 가질 필요 없이 부모 컴포넌트의 state를 가져다 쓰면 된다.

💡 Lifting State Up

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

실행화면





참고

인프런 - 처음 만난 리액트

post-custom-banner

0개의 댓글