[React] Controlled Components, Lifting State Up, Composition vs Inheritance

2025. 5. 12. 11:43·FrontEnd/React

 

☁️충북대 구름톤 유니브 4기

1. React의 Form


1.1 Controlled Components

값이 React의 state에 의해 제어되는 폼 요소를 말합니다.

 

1.1.1 예시

// input 태그
<input type="text" value={value} onChange={handleChange} />

// textarea 태그
<textarea value={value} onChange={handleChange} />

// select 태그
<select value={value} onChange={handleChange}>
  <option value="apple">사과</option>
  <option value="banana">바나나</option>
  <option value="grape">포도</option>
  <option value="watermelon">수박</option>
</select>

1.2 textarea 태그

긴 텍스트 입력을 받기 위한 태그입니다.

import React, { useState } from 'react';

function RequestForm() {
  const [value, setValue] = useState('요청사항을 입력하세요.');

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

  const handleSubmit = (event) => {
    alert('입력한 요청사항: ' + value);
    event.preventDefault();
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        요청사항:
        <textarea value={value} onChange={handleChange} />
      </label>
      <button type="submit">제출</button>
    </form>
  );
}

1.3 select 태그

드롭다운 형태로 옵션을 선택할 수 있는 태그입니다.

import React, { useState } from 'react';

function FruitSelect() {
  const [selectedFruit, setSelectedFruit] = useState('grape');

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

  return (
    <form>
      <label>
        과일 선택:
        <select value={selectedFruit} onChange={handleChange}>
          <option value="apple">사과</option>
          <option value="banana">바나나</option>
          <option value="grape">포도</option>
          <option value="watermelon">수박</option>
        </select>
      </label>
      <p>선택한 과일: {selectedFruit}</p>
    </form>
  );
}

1.3.1 다중 선택 예시

<select multiple={true} value={selectedOptions} onChange={handleChange} />
const selected = Array.from(event.target.selectedOptions, (option) => option.value);

1.4 file input 태그

사용자가 파일을 선택할 수 있도록 하는 태그입니다.

  • 파일 입력은 읽기 전용으로, uncontrolled component입니다.
import React, { useState } from 'react';

function FileUploadExample() {
  const [fileName, setFileName] = useState('');

  const handleFileChange = (event) => {
    const file = event.target.files[0];
    if (file) {
      setFileName(file.name);
    }
  };

  return (
    <form>
      <label>
        파일 업로드:
        <input type="file" onChange={handleFileChange} />
      </label>
      <p>선택된 파일: {fileName}</p>
    </form>
  );
}

1.5 여러 개의 상태 선언 및 입력 처리

여러 입력 필드가 있을 경우, 각각의 useState를 사용하여 상태를 관리합니다.

import React, { useState } from 'react';

function Reservation() {
  const [haveBreakfast, setHaveBreakfast] = useState(true);
  const [numberOfGuest, setNumberOfGuest] = useState(2);

  const handleSubmit = (event) => {
    alert(`아침식사 여부: ${haveBreakfast}, 방문객 수: ${numberOfGuest}`);
    event.preventDefault();
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        아침식사 여부:
        <input
          type="checkbox"
          checked={haveBreakfast}
          onChange={(e) => setHaveBreakfast(e.target.checked)}
        />
      </label>
      <br />
      <label>
        방문객 수:
        <input
          type="number"
          value={numberOfGuest}
          onChange={(e) => setNumberOfGuest(e.target.value)}
        />
      </label>
      <br />
      <button type="submit">제출</button>
    </form>
  );
}

1.6 input에 null을 넘기면?

<input value={null} />
  • value={null}을 설정하면 React는 해당 input을 uncontrolled component로 간주합니다.
  • 이후에는 사용자가 자유롭게 입력할 수 있게 됩니다.

2. Lifting State Up

여러 컴포넌트가 같은 상태를 공유해야 할 경우, 상태를 공통 부모 컴포넌트로 끌어올립니다.

function Parent() {
  const [value, setValue] = useState('');

  return (
    <>
      <ChildA value={value} onChange={setValue} />
      <ChildB value={value} />
    </>
  );
}

function ChildA({ value, onChange }) {
  return (
    <input value={value} onChange={(e) => onChange(e.target.value)} />
  );
}

function ChildB({ value }) {
  return <p>입력값: {value}</p>;
}

2.1 언제 써야 할까?

  • 여러 컴포넌트가 동일한 데이터를 기반으로 렌더링될 때
  • 자식 컴포넌트 간 상태 동기화가 필요할 때
  • 데이터 흐름을 명확히 유지하고 싶을 때

3. Composition vs Inheritance

React는 상속보다 합성(Composition)을 권장합니다.

 

3.1 Composition - Containment

하위 컴포넌트를 포함하는 형태의 합성 방법

  • sidebar, dialog 같은 box형태의 컴포넌트는 자신의 하위 컴포넌트를 미리 알 수 없다.
  • childen 이라는 props를 사용해서 조합.
function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">{props.left}</div>
      <div className="SplitPane-right">{props.right}</div>
    </div>
  );
}

function App() {
  return (
    <SplitPane left={<Contacts />} right={<Chat />} />
  );
}

3.2 Composition - Specialization

범용적인 개념을 구별이 되도록 구체화하는 것

  • 객체 지향 언어에서는 상속으로 구현. 여기서는 합성으로 구현.
function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">{props.title}</h1>
      <p className="Dialog-message">{props.message}</p>
    </FancyBorder>
  );
}

function WelcomeDialog() {
  return (
    <Dialog
      title="어서 오세요"
      message="우리 사이트에 방문하신 것을 환영합니다!"
    />
  );
}

3.3 상속보다 합성을 추천하는 이유

  • 컴포넌트를 더 작게 쪼개고,
  • 필요한 컴포넌트들을 조합해서 유연하게 UI를 구성할 수 있기 때문입니다.
  •  

 

'FrontEnd > React' 카테고리의 다른 글

[React] Context API  (0) 2025.05.20
[React] useState와 useEffect  (0) 2025.04.10
[React] REACT란? / JSX란? / Element란?  (0) 2025.04.03
'FrontEnd/React' 카테고리의 다른 글
  • [React] Context API
  • [React] useState와 useEffect
  • [React] REACT란? / JSX란? / Element란?
yuvnn
yuvnn
파이팅!
  • yuvnn
    yuvnn BLOG
    yuvnn
  • 전체
    오늘
    어제
    • 분류 전체보기 (8)
      • git (2)
      • CS fundamental (1)
        • data structure (1)
        • Computer Networks (0)
        • OS, Operating System (0)
      • FrontEnd (4)
        • React (4)
        • Figma (0)
      • ML, Machine Learning (1)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
yuvnn
[React] Controlled Components, Lifting State Up, Composition vs Inheritance
상단으로

티스토리툴바