열렬히.뛰기

state 공유하기

웹 프로그래밍 > React > 리액트의 기초 > state 공유하기

state 공유하기

  • state를 공유해서 여러 개의 하위 컴포넌트에서 이를 사용하는 것
  • state 공유를 통해 온도를 받아서 섭씨와 화씨로 각각 표기하는 것을 구현.

예시 코드

TemperatureInput.jsx

javascript
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;

Calculator.jsx

javascript
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;

코드 설명

  1. 상태 선언 및 관리 (Calculator 컴포넌트)
  • Calculator 컴포넌트는 두 가지 상태를 관리한다: temperature와 scale.
javascript
const [temperature, setTemperature] = useState("");
const [scale, setScale] = useState("c");
  1. 상태 변경 핸들러 (Calculator 컴포넌트):
  • Calculator는 두 가지 상태 변경 함수를 정의한다: handleCelsiusChange, handleFahrenheitChange
javascript
const handleCelsiusChange = (temperature) => {
    setTemperature(temperature);
    setScale("c");
};

const handleFahrenheitChange = (temperature) => {
    setTemperature(temperature);
    setScale("f");
};
  • 이 함수들은 TemperatureInput 컴포넌트에서 호출되어 상태를 변경한다.
  1. 상태 변환 및 전달 (Calculator 컴포넌트):
  • 만약, 어떠한 값이 들어오면 Calculator 컴포넌트는 현재 상태를 사용하여 섭씨와 화씨 값을 계산한다.
javascript
const celsius = 
    scale === "f" ? tryConvert(temperature, toCelsius) : temperature;
const fahrenheit = 
    scale === "c" ? tryConvert(temperature, toFahrenheit) : temperature;
  • 계산 후 이 값을 TemperatureInput 컴포넌트에 전달한다.
  1. 하위 컴포넌트에 상태 전달 (Calculator 컴포넌트):
  • 두 개의 TemperatureInput 컴포넌트는 각각 섭씨와 화씨 값을 표시한다.
  • 이후 상태 변경 핸들러를 prop으로 전달받는다.
javascript
<TemperatureInput
    scale="c"
    temperature={celsius}
    onTemperatureChange={handleCelsiusChange}
/>
<TemperatureInput
    scale="f"
    temperature={fahrenheit}
    onTemperatureChange={handleFahrenheitChange}
/>
  1. 상태 변경 요청 (TemperatureInput 컴포넌트):
  • TemperatureInput 컴포넌트는 입력한 값을 상위 컴포넌트로 전달하기 위해 props.onTemperatureChange를 호출한다
javascript
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>
    )
}

이 함수는 Calculator 컴포넌트에서 전달받은 상태 변경 핸들러이다.