state 끌어올리기

5o_hyun·2022년 12월 27일
0
post-thumbnail

여러개의 컴포넌트 사이에서 state를 공유하는 방법에 대해 알아보자.

shared state (공유된 state)

하나의 데이터를 여러개의 컴포넌트를 공유해야하는경우, 자식의 컴포넌트들이 공통된 부모 컴포넌트의 state를 공유하는것이다.

하위 컴포넌트에서 state공유하기


섭씨나 화씨온도 둘 중 아무거나 입력해도 자동으로 계산되고, 100도씨이상에서는 물이 끓는지 아닌지를 알려준다.


TemperatureInput 컴포넌트는 props로 temperature, scale을 받아서 표시해주며,
온도값이 변경되었을때는 props로 onTemperatureChange 함수를 호출하여 상위 컴포넌트로 변경된값을 전달하게 된다.

TemperatureInput.jsx

import React from "react";

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

const TemperatureInput = (props) => {
  const handleChange = (e) => {
    props.onTemperatureChange(e.target.value);
  };
  return (
    <fieldset>
      <legend>온도를 입력하세요.{scaleNames[props.scale]}</legend>
      <input value={props.temperature} onChange={handleChange} />
    </fieldset>
  );
};

export default TemperatureInput;

Calculator 컴포넌트는 앞에서 만든 TemperatureInput을 사용하여 섭씨와 화씨 두가지의 입력양식을 제공한다.
또한 모든 온도를 섭씨로 변환하여 BoilingVerdict 컴포넌트로 전달해서, 물이 끓는지 아닌지를 출력한다.

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

const BoilingVerdict = (props) => {
  if (props.celsius >= 100) {
    return <p>물이 끓습니다.</p>;
  }
  return <p>물이 끓지 않습니다.</p>;
};

const toCelsius = (fahrenheit) => {
  return ((fahrenheit - 32) * 5) / 9;
};

const toFahrenheit = (celsius) => {
  return (celsius * 9) / 5 + 32;
};

const 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();
};

const Calculator = (props) => {
  const [temperature, setTemperature] = useState("");
  const [scale, setScale] = useState("c");

  const handleFahrenheitChange = (temperature) => {
    setTemperature(temperature);
    setScale("f");
  };
  const handleCelsiusChange = (temperature) => {
    setTemperature(temperature);
    setScale("c");
  };

  const celsius =
    scale === "f" ? tryConvert(temperature, toCelsius) : temperature;
  const fahrenheit =
    scale === "c" ? tryConvert(temperature, toFahrenheit) : temperature;
  return (
    <div style={{ padding: 16 }}>
      <TemperatureInput
        scale="c"
        temperature={celsius}
        onTemperatureChange={handleCelsiusChange}
      />
      <TemperatureInput
        scale="f"
        temperature={fahrenheit}
        onTemperatureChange={handleFahrenheitChange}
      />
      <BoilingVerdict celsius={parseFloat(celsius)} />
    </div>
  );
};

export default Calculator;
profile
학생 점심 좀 차려

0개의 댓글