Task 관리 & Prop Drilling 이해하기

장효정·2025년 12월 12일

Udemy React 강의 160번 정리

이번 강의의 핵심은 크게 두 가지.

  1. Task를 어떻게 상태로 관리할 것인가
  2. 왜 prop drilling이 문제가 되는가 (그리고 왜 다음에 다른 방법을 배우는지)

1. Task 입력: ref가 아니라 state를 쓰는 이유

상황

  • NewTask 컴포넌트에 input + Add Task 버튼이 있음
  • 버튼을 누르면 1) 입력된 task를 저장해야 하고, 2) input을 비워야 함

ref로 하면 안 될까?

가능은 함.
하지만 여기서는 React가 DOM을 제어하도록 두는 연습을 하기 위해 state를 사용함.

그래서 선택한 방식: controlled input (state)

import { useState } from 'react';

export default function NewTask({ onAdd }) {
  const [enteredTask, setEnteredTask] = useState('');

  function handleChange(event) {
    setEnteredTask(event.target.value);
  }

  function handleClick() {
    // 1. 먼저 입력된 값을 App 컴포넌트로 보내기
    // 2. 이 입력란을 빈 칸으로 리셋하기
    onAdd(enteredTask);
    setEnteredTask('');
  }

  return (
    <div className="flex items-center gap-4">
      <input
        type="text"
        className="w-64 px-2 py-1 rounded-sm bg-stone-200"
        onChange={handleChange}
        value={enteredTask}
      />
      <button
        className="text-stone-700 hover:text-stone-950"
        onClick={handleClick}
      >
        Add Task
      </button>
    </div>
  );
}
  • onChange → 입력값을 state에 저장
  • value={enteredTask} → state를 다시 input에 반영
  • 버튼 클릭 시: (1) task 전달 (2) setEnteredTask('') → input 초기화

즉, 입력값을 직접 DOM에서 조작하지 않고, state로 관리.

2. Task는 어디에 저장해야 할까?

중요한 설계 포인트

  • Task는 특정 Project에 속함
  • Project와 Task를 모두 알고 있는 곳은? App 컴포넌트
  • 그래서 1) Task 배열 상태는 App에 둔다 2) Task 추가 및 삭제 함수도 App에 둔다

3. Task 추가 흐름 (전체 데이터 흐름)

데이터 흐름 요약

NewTask
  ↓ (onAdd)
Tasks
  ↓
SelectedProject
  ↓
App (handleAddTask)

이게 바로 prop drilling임.

4. Prop Drilling이란?

정의

필요한 컴포넌트가 아닌데도 단지 전달만 하기 위해 props를 계속 내려보내는 것

실제로 여기서 발생한 일

  • handleAddTask 함수는 App에 있음
  • 하지만 버튼은 NewTask에 있음
  • 중간 컴포넌트들: SelectedProject | Tasks
  • 이 컴포넌트들은 함수를 쓰지도 않으면서 전달만 함
App
 └─ SelectedProject
     └─ Tasks
         └─ NewTask (여기서 실제로 사용)

중간 컴포넌트들이 점점 지저분해짐


이 강의에서는 Task 기능을 구현하는 것보다 state를 어디에 두어야 하는지와 prop drilling이 왜 불편해지는지를 직접 체감하는 게 핵심이었다.

다음 강의에서는 이 문제를 더 깔끔하게 해결하는 방법을 배운다.

0개의 댓글