REACT/[inflearn] 처음만난 리액트

12강. Lifting State Up

web_seul 2022. 11. 22. 21:34
반응형

Shared State

Shared State : State에 있는 데이터를 여러개의 하위 컴포넌트에서 공통적으로 사용하는 경우, 하위 컴포넌트가 공통된 부모 컴포넌트의 state를 공유하여 사용하는 것, 하위 컴포넌트의 state를 공통 상위 컴포넌트로 올림

 

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

//물의 끓음 여부를 알려주는 컴포넌트
function BilingVerdic(props){
  if(props.celsius >= 100) {
    return <p>물이 끓습니다.</p>;
  }
  return <p>물이 끓지 않습니다.</p>;
}

//
function Calculator(props){
  const [temperature, setTemperature] = useState('');
  const handleChange = (event) => {
    setTemperature(event.target.value);
  }
  return(
    <fieldset>
      <legend>섭씨 온도를 입력하세요.</legend>
      <input
        value={temperature}
        onChange={handleChange}>
      <BoilingVerdict
        celsius={parseFloat(temperature)}>
    </fieldset>
  )
}
//State 공유하기
function Calculator(props){
  return(
    <div>
      <TemperatureInput scale="c">
      <TemperatureInput scale="f">
    </div>
  );
}

//입력 컴포넌트 추출하기 : 구분하여 입력받기위함, 재사용가능
const scaleNames = {
  c: '섭씨',
  f: '화씨'
}
function TemperatureInput(props){
  const [temperature, setTemperature] = useState('');
  const handleChange = (event) => {
      //lifting state
      //setTemperature(event.target.value);
      props.onTemperatureChange(event.target.value);
  }
  return(
    <fieldset>
      <legend>온도를 입력해줏요(단위:{scaleNames[props.scale]});</legend>
      //lifting state
      //<input value={temperature} onChange={handleChange}>
      <input value={props.temperature} onChange={handleChange}>
    </fieldset>
  )
}

//온도변환함수 작성하기
function toCelsius(fahrenheit){
  return (fahrenheit - 32) *5 /9;
}
function toFahrenheit(celsius){
  return (celsius *9 /5) + 32;
}

//값변환
//tryConvert('abc', toCelsius); empty string리턴
//tryConvert('10.22', toFahrenheit); '50.396'리턴
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 [sacle, 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>
  )
}

 

(실습) 섭씨온도와 화씨온도 표시하기

//TemperatureInput.jsx
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
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;

 

반응형

'REACT > [inflearn] 처음만난 리액트' 카테고리의 다른 글

14강. Context  (0) 2022.12.02
13강. Composition vs Inheritance  (0) 2022.11.30
11강. Forms  (0) 2022.11.21
10강. List and Keys  (0) 2022.11.11
9강. Conditional Rendering  (0) 2022.11.10