TIL - 20260211

juni·2026년 2월 11일

TIL

목록 보기
265/316

0211 리액트 기초 복습 (3/N): 컴포넌트 간의 소통과 동적 렌더링


✅ 1. 상향식 데이터 전달 (Lifting State Up)

  • React의 기본 데이터 흐름은 하향식(Top-Down)입니다 (부모 → 자식, via Props). 하지만 자식 컴포넌트에서 발생한 데이터를 부모 컴포넌트로 전달해야 할 때가 많습니다. (e.g., 자식의 폼에서 입력한 데이터를 부모의 목록 상태에 추가)

  • 핵심 원리: 부모가 데이터를 처리할 함수를 자식에게 Props로 전달하고, 자식은 그 함수를 호출하여 데이터를 "위로" 보냅니다.

➕ 처리 흐름

  1. [부모] 자식으로부터 받은 데이터를 처리할 함수를 정의합니다.

  2. [부모] 해당 함수를 자식 컴포넌트에 Props로 전달합니다. (e.g., onSaveData={...})

  3. [자식] 특정 이벤트(e.g., 폼 제출)가 발생했을 때, Props로 전달받은 함수를 호출하면서 전달할 데이터를 인자로 넘깁니다.

  4. [부모] 함수가 호출되면서 자식의 데이터가 부모의 상태를 업데이트하고, 리렌더링이 발생합니다.

    // 부모 컴포넌트: App.js
    function App() {
      const [expenses, setExpenses] = useState([]);
    
      // 1. 자식의 데이터를 받아 처리할 함수
      const addExpenseHandler = (expenseData) => {
        setExpenses((prevExpenses) => [expenseData, ...prevExpenses]);
      };
    
      return (
        <div>
          {/* 2. 자식에게 함수를 props로 전달 */}
          <NewExpenseForm onAddExpense={addExpenseHandler} />
          <ExpenseList items={expenses} />
        </div>
      );
    }
    
    // 자식 컴포넌트: NewExpenseForm.js
    function NewExpenseForm(props) {
      const submitHandler = (event) => {
        event.preventDefault();
        const newExpense = { /* ... 폼 데이터 ... */ };
        
        // 3. props로 받은 함수를 호출하여 데이터를 위로 전달
        props.onAddExpense(newExpense);
      };
      
      return <form onSubmit={submitHandler}>...</form>;
    }

✅ 2. 동적 리스트 렌더링

  • 배열에 담긴 데이터를 화면에 목록 형태로 렌더링할 때는 JavaScript의 map() 메서드를 사용합니다. map()은 배열의 각 요소를 순회하며, 각 요소를 JSX 엘리먼트로 변환한 새로운 배열을 반환합니다.

key Prop의 중요성

  • map()을 사용하여 리스트를 렌더링할 때는, 각 엘리먼트에 key라는 특별한 Prop을 반드시 포함해야 합니다.

  • key의 역할: React가 리스트의 항목이 변경, 추가, 또는 삭제되었을 때 어떤 항목을 변경해야 하는지 효율적으로 식별하기 위해 사용됩니다. key는 React에게 각 항목의 "신분증"과 같습니다.

  • 좋은 key: 각 항목을 고유하게 식별할 수 있는 안정적인 값이어야 합니다. (e.g., 데이터의 id) 배열의 인덱스는 데이터가 변경되지 않는 정적인 리스트에서만 최후의 수단으로 사용해야 합니다.

    function ExpenseList(props) {
      return (
        <ul>
          {/* 배열(props.items)을 map으로 순회하며 ExpenseItem 컴포넌트 렌더링 */}
          {props.items.map((expense) => (
            <ExpenseItem
              key={expense.id} // 각 항목을 식별할 고유하고 안정적인 key
              title={expense.title}
              amount={expense.amount}
            />
          ))}
        </ul>
      );
    }

✅ 3. 조건부 렌더링 (Conditional Rendering)

  • 특정 조건(State, Props 등)에 따라 다른 UI를 보여주는 것을 의미합니다. 이를 통해 동적이고 상황에 맞는 UI를 만들 수 있습니다.
방법사용 사례예시 코드
삼항 연산자if-else와 같이 두 가지 경우 중 하나를 렌더링할 때{isEditing ? <EditForm /> : <DisplayView />}
논리 && 연산자특정 조건이 참일 때만 엘리먼트를 렌더링할 때{isLoggedIn && <UserProfile />}
if문과 변수렌더링 로직이 복잡하여 JSX 밖에서 처리해야 할 때let content = <p>No items found.</p>;
if (items.length > 0) { ... }
return <div>{content}</div>;

➕ 목록이 비어있을 때 다른 UI 보여주기 예시

function ExpenseList(props) {
  // if문과 변수를 사용한 조건부 렌더링
  if (props.items.length === 0) {
    return <h2 className="expenses-list__fallback">Found no expenses.</h2>;
  }

  return (
    <ul className="expenses-list">
      {props.items.map((expense) => (
        <ExpenseItem
          key={expense.id}
          title={expense.title}
          amount={expense.amount}
        />
      ))}
    </ul>
  );
}

📌 요약

  • 자식에서 부모로 데이터를 전달할 때는, 부모가 함수를 Props로 내려주고 자식이 그 함수를 호출하는 상향식 데이터 전달 패턴을 사용합니다.
  • 배열 데이터를 UI 목록으로 변환할 때는 map() 메서드를 사용하며, 각 항목에는 반드시 고유한 key Prop을 지정하여 렌더링 효율을 높여야 합니다.
  • 상황에 따라 다른 UI를 보여주기 위해 삼항 연산자, && 연산자, if 등 다양한 조건부 렌더링 기법을 활용합니다.

0개의 댓글