[React] UI 표현하기 - 조건부 렌더링

Gyuhan Park·2024년 1월 30일
0

공식문서

목록 보기
6/10

[ 요약 ]

  • 조건에 따라 다른 JSX 트리를 반환 할 수 있음
  • 삼항 연산자(? :)를 사용하여 중복된 코드 제거 가능 (복잡한 조건식 지양)
  • 조건부 렌더링에 의해 컴포넌트가 지저분해질 경우 자식 컴포넌트 추출
  • 조건에 따라 JSX를 렌더링하거나 아무것도 렌더링하지 않을 때는 논리 AND 연산자(&&) 사용
  • JS는 자동으로 왼쪽을 boolean 으로 변환하여 && 왼쪽에는 숫자

[ 학습 내용 ]

  • 조건에 따라 다른 JSX를 반환하는 방법
  • JSX 조각을 조건부로 포함하거나 제외하는 방법
  • React 코드에서 흔히 볼 수 있는 조건부 문법

📘 조건부로 JSX 반환하기

짐을 챙긴 여부(isPacked)에 따라 다른 JSX 반환
isPacked prop이 true이면 Item 컴포넌트는 다른 JSX 트리를 반환

function Item({ name, isPacked }) {
  if (isPacked) {
    return <li className="item">{name}</li>;
  }
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

📘 조건부로 null을 사용하여 아무것도 반환하지 않기

짐을 챙긴 항목을 전혀 보여주지 않는다고 가정
컴포넌트는 반드시 무언가를 반환해야 하는데 아무것도 렌더링하고 싶지 않을 경우에 null 반환
실제로 컴포넌트에서 null을 반환하는 것은 흔한 경우는 아님

if (isPacked) {
  return null;
}
return <li className="item">{name}</li>;

📘 조건부로 JSX 포함시키기

조건문에 따라 컴포넌트에 의해 JSX 트리 반환
렌더링 된 출력 결과에서 일부 중복 존재
→ 코드 수정, 유지보수 어려움

<li className="item">{name}</li>
<li className="item">{name}</li>

✅ 삼항 조건 연산자

“isPacked가 참이면 (?) name + ' ✔'을 렌더링하고, 그렇지 않으면 (:) name을 렌더링 한다.”

// ❌
if (isPacked) {
  return <li className="item">{name}</li>;
}
return <li className="item">{name}</li>;

// ✅
return (
  <li className="item">
    {isPacked ? name + ' ✔' : name}
  </li>
);

소괄호() 를 추가하여 중첩된 태그 반환 가능
간단한 조건에 잘 어울리지만, 적당히 사용 권장
중첩된 조건부 마크업이 너무 많아 컴포넌트가 지저분해질 경우 자식 컴포넌트를 추출 하여 정리

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {isPacked ? (
        <del>
          {name + ' ✔'}
        </del>
      ) : (
        name
      )}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

🚨 두 예제는 완전히 동일할까요?

<li>의 두 가지 다른 “인스턴스”를 만들 수 있기 때문에 다르다고 생각할 수 있지만,
JSX 엘리먼트는 내부 상태를 보유하지 않으며 실제 DOM 노드가 아니기 때문에 인스턴스 ❌
→ 완전히 동일한 코드

✅ 논리 AND 연산자 (&&)

조건이 참일 때 일부 JSX를 렌더링하거나, 그렇지 않으면 아무것도 렌더링하지 않을 때 를 나타내는 경우 사용
왼쪽(조건)이 true : 오른쪽(체크 표시)의 값을 반환
조건이 false : 전체 표현 식이 false
React는 falsenull 또는 undefined처럼 JSX 트리의 “구멍”으로 간주하고 그 자리에 렌더링 ❌

return (
  <li className="item">
    {name} {isPacked && '✔'}
  </li>
);

🚨 주의하세요!

&&의 왼쪽에 숫자 ❌
조건을 테스트하기 위해 JavaScript는 자동으로 왼쪽을 boolean 으로 변환
그러나 왼쪽이 0이면 전체 식이 (0)을 얻게 되고, 리액트는 아무것도 아닌 0을 렌더링할 것
이 문제를 해결하려면 messageCount > 0 && <p>New messages</p> 처럼 왼쪽을 boolean으로 만들기

📘 변수에 조건부로 JSX를 할당하기

  1. if문과 let으로 선언한 변수를 사용
  2. 변수를 선언하고 true일 경우 JSX표현식을 itemContent 에 재할당
  3. 반환된 JSX 트리에 중괄호를 사용하고 이전에 계산된 식을 JSX 내부에 중첩하여 변수를 포함
function Item({ name, isPacked }) {
  let itemContent = name;
  if (isPacked) {
    itemContent = name + " ✔";
  }
  return (
    <li className="item">
      {itemContent}
    </li>
  );
}
export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

https://ko.react.dev/learn/conditional-rendering

profile
단단한 프론트엔드 개발자가 되고 싶은

0개의 댓글