TIL - 20260214

juni·2026년 2월 14일

TIL

목록 보기
268/317

0214 리액트 기초 복습 (6/N): 종합 응용 및 정리


✅ 1. React 개발의 전체 흐름: "생각하기"

  • React로 애플리케이션을 만드는 것은 단순히 코드를 작성하는 것을 넘어, UI를 어떻게 컴포넌트 단위로 분해하고, 데이터가 어떻게 흐를지를 설계하는 과정입니다.

  • "Todo List" 애플리케이션을 만든다고 가정해봅시다.

    1. UI를 컴포넌트 계층 구조로 나누기:

      • App (전체를 감싸는 루트 컴포넌트)
        • TodoForm (새로운 할 일을 입력하고 추가하는 폼)
        • TodoList (할 일 목록을 보여주는 리스트)
          • TodoItem (개별 할 일 항목)
    2. State가 어디에 있어야 할지 결정하기:

      • "할 일 목록"(todos 배열)은 TodoForm에서 새로 추가되고, TodoList에서 보여져야 합니다.
      • 이처럼 여러 컴포넌트에서 공유해야 하는 상태는, 그 컴포넌트들의 가장 가까운 공통 부모에 위치해야 합니다. 이 경우, App 컴포넌트가 todos 상태를 관리하는 것이 가장 적합합니다.

✅ 2. 데이터 흐름의 완성: 하향식(Props)과 상향식(Lifting State Up)

  • 위에서 설계한 구조를 바탕으로, 데이터가 어떻게 흐르는지 다시 한번 정리합니다.

➕ 하향식 데이터 흐름 (Props)

  • 부모 → 자식으로 데이터가 전달됩니다.
    1. App 컴포넌트는 todos 상태 배열을 TodoList 컴포넌트에 items라는 prop으로 전달합니다.
    2. TodoList는 전달받은 items 배열을 map()으로 순회하며, 각 todo 객체를 TodoItem 컴포넌트에 prop으로 전달합니다.

➕ 상향식 데이터 흐름 (Lifting State Up)

  • 자식 → 부모로 데이터(이벤트)가 전달됩니다.
    1. 항목 추가:
      • App 컴포넌트는 todos 상태를 변경하는 함수(addTodoHandler)를 정의합니다.
      • 이 함수를 TodoForm 컴포넌트에 onAddTodo라는 prop으로 전달합니다.
      • TodoForm은 폼이 제출될 때, props.onAddTodo()를 호출하여 입력된 데이터를 App 컴포넌트로 올려보냅니다.
    2. 항목 삭제:
      • App 컴포넌트는 특정 id의 항목을 삭제하는 함수(deleteTodoHandler)를 정의합니다.
      • 이 함수는 TodoList를 거쳐 TodoItem까지 prop으로 전달됩니다.
      • TodoItem의 삭제 버튼이 클릭되면, props.onDelete()를 자신의 id와 함께 호출하여 App 컴포넌트의 상태를 변경합니다.

✅ 3. 동적 UI의 구현: 렌더링과 Side Effects

  • 상태와 데이터 흐름이 설계되면, 이를 바탕으로 실제 UI를 동적으로 그려냅니다.

➕ 동적 리스트 렌더링 (map & key)

  • TodoList 컴포넌트는 props로 받은 배열을 map() 메서드를 사용하여 TodoItem 컴포넌트의 배열로 변환합니다.
  • 이때, 각 TodoItem에는 React가 각 항목을 효율적으로 식별할 수 있도록 고유하고 안정적인 key prop (e.g., key={todo.id})을 반드시 지정해야 합니다.

➕ 조건부 렌더링

  • TodoList 컴포넌트에서, 만약 props.items 배열의 길이가 0이라면 "할 일이 없습니다."와 같은 메시지를 보여주고, 0보다 크면 목록을 렌더링하도록 조건부 렌더링을 적용합니다.
    {props.items.length === 0 ? (
      <p>할 일이 없습니다.</p>
    ) : (
      <ul>...</ul>
    )}

➕ Side Effects (useEffect)

  • 만약 todos 목록이 변경될 때마다 브라우저의 localStorage에 자동으로 저장하고 싶다면, 이는 Side Effect에 해당합니다.
  • useEffect를 사용하여 todos 상태를 의존성 배열에 넣으면, todos가 변경될 때마다 localStorage.setItem()을 실행하는 로직을 구현할 수 있습니다.
    useEffect(() => {
      localStorage.setItem('todos', JSON.stringify(todos));
    }, [todos]); // todos 배열이 변경될 때마다 이 효과가 실행됨

📌 최종 요약: React 기초의 핵심 사이클

  1. 컴포넌트 분해: UI를 작고 재사용 가능한 컴포넌트 단위로 나눕니다.
  2. 상태 위치 선정: 여러 컴포넌트가 공유하는 상태는 가장 가까운 공통 부모에 둡니다.
  3. 데이터 전달:
    • 부모에서 자식으로는 Props를 통해 데이터를 전달합니다 (하향식).
    • 자식에서 부모로는 함수를 Props로 전달하여 호출하는 방식으로 이벤트를 전달합니다 (상향식).
  4. 동적 렌더링:
    • State (useState)가 변경되면 컴포넌트가 자동으로 리렌더링됩니다.
    • map()key를 사용하여 배열 데이터를 리스트로 렌더링합니다.
    • 조건부 렌더링을 통해 상황에 맞는 UI를 보여줍니다.
  5. Side Effects 처리:
    • API 요청, localStorage 접근 등 렌더링과 직접 관련 없는 작업은 useEffect를 사용하여 처리합니다.
  • 이러한 개념들이 유기적으로 연결되어, 선언적이고 효율적인 React 애플리케이션을 구성합니다.

0개의 댓글