개발/리액트

리액트 핵심만 훑어보자 #13 컴포넌트 간 상태 공유

brobro332 2025. 3. 11. 21:26
반응형
📘 『소플의 처음 만난 리액트』를 읽고 정리한 글입니다.

 

컴포넌트 간 상태 공유

  • 어떤 컴포넌트의 상태를 여러 개의 하위 컴포넌트에서 공통적으로 사용하는 것을 의미한다.

 

실습

Calculator.jsx
├── BoilingVerdict.jsx
└── TemperatureInput.jsx
  • 오늘 실습 프로그램의 구조이다.

 
Calulator.jsx

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

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;
  • 해당 컴포넌트의 상태에 접근할 수 있는 함수를 자식 컴포넌트에 공유하고 있다.
  • 상기 코드에서는 onTemperatureChange 속성을 통해 전달하고 있다.

 
BoilingVerdict.jsx

import React from "react";

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

export default BoilingVerdict;

 
 
TemperatureInput.jsx

// 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;
  • 부모 컴포넌트에게서 전달된 props.onTemperatureChange 속성을 통해 부모 컴포넌트에 영향을 주고 있다.
  • 이렇게 하위 컴포넌트의 상태를 공통된 부모 컴포넌트로 끌어올려서 공유하는 방식을 상태 끌어올리기라고 한다.

 

마치며

공통 상태를 부모 컴포넌트에서 관리하는 것은 코드를 효율적으로 관리하는 방법 중 하나이다.
꼭 리액트가 아니더라도 어떤 영역이든 공통적으로 관리할 수 있다면 그렇게 하는 것이 좋은 것 같다.

요즘 화면 개발하면서 느끼는 건데.. 리액트 정말 제대로 하려면 한도 끝도 없는 것 같다.
화면 그리려면 시간도 엄청 잡아먹고, 컴포넌트를 어떻게 나눠야 할지 예상을 못해서 리팩토링 하는 데도 시간이 꽤 걸린다.

빨리 토이 프로젝트 서버 쪽 개발하고 싶은데 리액트에 발목이 붙잡혔다.. 😨 

 

이미지 출처

[React] Component 를 사용하는 기본적인 방법

컴포넌트는 React의 핵심 개념 중 하나이며, 이는 사용자 인터페이스(UI)를 구축하는 기반이다. 컴포넌트를 만들어보자. 우선 여기까지는 순수 JS의 선언 및 정의에 대한 구문이다. 리액트는 컴포

velog.io

 

소플 - soaple.io

소플

www.soaple.io