본문 바로가기
Front/React

[React] Shared State (섭씨 화씨 변환기 만들기)

by 오엥?은 2023. 4. 21.
반응형

 

Shared State

: State 에 있는 데이터를 여러 개의 하위 컴포넌트에서 공통적으로 사용하는 경우

하위 컴포넌트가 공통된 부모 컴포넌트의 state 를 공유하여 사용하는 것

 

 

  • 하위 컴포넌트에서 State 공유하기

- 물의 끓음 여부를 알려주는 컴포넌트

import React from "react";

function BoilingVerdict(props) {
    if (props.celsius >= 100) {
    	return <p style={{margin: 10, color: "blue"}}>물이 끓습니다.</p>;
    }
    return <p style={{margin: 10, color: "red"}}>물이 끓지 않습니다.</p>;
}

export default BoilingVerdict
import React, {useState} from "react";
import BoilingVerdict from "./BoilingVerdict";

function Calculator(props) {
    const [temperature, setTemperature] = useState('');

    const handleChange = (event) => {
        setTemperature(event.target.value);
    }

    return (
        <fliedset>
            <legend style={{margin: 10}}>섭씨 온도를 입력하세요: </legend>
            <input 
                value={temperature}
                style={{margin: 10}}
                onChange={handleChange} />
            <BoilingVerdict celsius={parseFloat(temperature)} />
        </fliedset>
    )
}

export default Calculator;

 

100도 미만의 온도를 입력하면 "물이 끓지 않습니다." 문구가 뜨고,

100도 이상의 온도를 입력하면 "물이 끓습니다." 문구가 뜬다.

 

 

  • 입력 컴포넌트 추출하기

 : 섭씨 온도와 화씨 온도를 각각 따로 입력받을 수 있게 하여, 재사용이 가능한 형태로 효율적인 컴포넌트를 만든다.

import React, { useState } from "react";

const scaleNames = {
    c: '섭씨',
    f: '화씨'
};

function TemperatureInput(props) {
    const [temperature, setTemperature] = useState('');

    const handleChange = (event) => {
        setTemperature(event.target.value);
    }

    return (
        <fliedset>
            <legend  style={{margin: 10}}>
                온도를 입력해 주세요 ( 단위: {scaleNames[props.scale]} )
            </legend>
            <p style={{margin: 10}}> : <input value={temperature} onChange={handleChange} /></p>
        </fliedset>
    )
}

export default TemperatureInput
import React, {useState} from "react";
import TemperatureInput from "./TemperatureInput";

function Calculator(props) {
    return (
        <div>
            <TemperatureInput scale="c" />
            <TemperatureInput scale="f" />
        </div>
    )
}

export default Calculator;

이렇게 하나의 코드로 두 가지 input 을 받을 수 있게 만들 수 있다.

 

 

 

 섭씨온도와 화씨온도 표시하기

  • src > chapter_12 > TemperatureInput.jsx
import React from "react";

const scaleNames = {
    c: "섭씨",
    f: "화씨",
};

function TemperatureIput(props) {
    const handleChange = (event) => {
        props.onTemperatureChange(event.target.value);
    };

    return (
        <fieldset style={{ boxShadow: '5px 5px 5px black' }}>
            <legend style={{ fontWeight: "bold" }}>
                온도를 입력해 주세요. (단위: {scaleNames[props.scale]})
            </legend>
            <p>: <input style={{ border: "3px solid", borderRadius: 5, paddingLeft: 10 }} value={props.temperature} onChange={handleChange} /></p>
        </fieldset>
    );
}

export default TemperatureIput;
  • src > chapter_12 > Calculator.jsx
import React, {useState} from "react";
import TemperatureInput from "../chapter_12/TemperatureInput";

function BoilingVerdict(props) {
    if (props.celsius >= 100) {
        return <p style={{ color: "blue", fontWeight: "bold", marginTop: 30, marginLeft: 30 }}>🏊‍♀️ 물이 끓습니다.</p>;
    }
    return <p style={{ color: "red", fontWeight: "bold", marginTop: 30, marginLeft: 30 }}>❌ 물이 끓지 않습니다.</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 style={{ margin: 20 }}>
            <TemperatureInput 
                scale="c"
                temperature={celsius}
                onTemperatureChange={handleCelsiusChange}
            />
            <br />
            <TemperatureInput 
                scale="f"
                temperature={fahrenheit}
                onTemperatureChange={handleFahrenheitChange}
            />
            <BoilingVerdict celsius={parseFloat(celsius)} />
        </div>
    );
}

export default Calculator;
  • npm start

섭씨에 숫자를 입력하면 화씨로 변환해 주고, 화씨에 숫자를 입력하면 섭씨로 변환해 준다.

그리고 그 온도가 물이 끓는 온도면 물이 끓는다는 문구가 뜨고, 물이 끓지 않는 온도면 물이 끓지 않는다는 문구가 뜬다.

 

 

 

반응형