조건부 렌더링
컴포넌트는 조건에 따라 다른 항목을 표시해야 하는 경우가 많습니다. 리액트는 if
문, &&
및 ? :
연산자와 같은 자바스크립트 문법을 사용하여 조건부로 JSX를 렌더링할 수 있습니다.
You will learn
- 조건에 따라 다른 JSX를 반환하는 방법
- JSX 조각을 조건부로 포함하거나 제외하는 방법
- React 코드에서 흔히 볼 수 있는 조건부 문법
조건부로 JSX 반환하기
짐을 챙겼는지 안 챙겼는지 표시할 수 있는 여러 개의 Item
을 렌더링하는 PackingList
컴포넌트가 있다고 가정해봅시다.
function Item({ name, isPacked }) { 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> ); }
Item
컴포넌트 중 일부는 isPacked
prop이 false
가 아닌 true
로 설정되어 있습니다. isPacked={true}
인 경우 짐을 챙긴 항목에 체크 표시(✔)를 추가하려고 합니다.
다음과 같이 if
/else
문으로 작성할 수 있습니다.
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
isPacked
prop이 true
이면 이 코드는 다른 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> ); }
각각의 경우를 수정해보고 반환 결과가 어떻게 달라지는지 확인해 보세요!
JavaScript의 if
와 return
문으로 분기 로직을 만드는 방법을 살펴보세요. React에서 제어 흐름(예: 조건문)은 JavaScript로 처리합니다.
조건부로 null
을 사용하여 아무것도 반환하지 않기
어떤 경우에는 아무것도 렌더링하고 싶지 않을 수 있습니다. 예를 들어, 짐을 챙긴 항목을 전혀 보여주지 않는다고 가정해보세요. 컴포넌트는 반드시 무언가를 반환해야 하는데 이 경우에 null
을 반환할 수 있습니다. 다음과 같이 말이죠.
if (isPacked) {
return null;
}
return <li className="item">{name}</li>;
isPacked
가 true
라면 컴포넌트는 아무것도 반환하지 않지만, false
라면 JSX가 반환될 것입니다.
function Item({ name, isPacked }) { if (isPacked) { return null; } 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
을 반환하는 것은 개발자가 렌더링하려고 할 때 놀랄 수 있기 때문에 흔한 경우는 아닙니다. 더 자주, 부모 컴포넌트 JSX에 컴포넌트를 조건부로 포함하거나 제외할 수 있습니다. 다음과 같이 해보세요!
조건부로 JSX 포함시키기
이전 예제에서는 어떤 항목(있는 경우)을 제어했습니다. 컴포넌트에 의해 JSX 트리가 반환되었습니다. 렌더링 된 출력 결과에서 이미 일부 중복이 발견되었을 수 있습니다.
<li className="item">{name} ✔</li>
이것은 아래와 매우 비슷합니다.
<li className="item">{name}</li>
두 조건부 분기가 모두 <li className="item">...</li>
를 반환합니다.
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
이 중복코드가 나쁘지는 않지만, 코드를 유지 보수하기 더 어렵게 만들 수 있습니다. className
을 바꾸고 싶다면 어떻게 해야 할까요? 코드상 두 군데를 수정해야 합니다! 이러한 상황에서 조건부로 약간의 JSX를 포함해 코드를 더 DRY(덜 반복적이게) 하게 만들 수 있습니다.
삼항 조건 연산자 (? :
)
JavaScript는 조건 연산자 또는 “삼항 조건 연산자”라는 조건식을 작성하기 위한 간단한 문법이 있습니다.
이 코드 대신,
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
다음과 같이 작성할 수 있습니다.
return (
<li className="item">
{isPacked ? name + ' ✔' : name}
</li>
);
“isPacked
가 참이면 (?
) name + ' ✔'
을 렌더링하고, 그렇지 않으면 (:
) name
을 렌더링 한다.” 라고 읽을 수 있습니다.
Deep Dive
<li>
의 두 가지 다른 “인스턴스”를 만들 수 있기 때문에 객체 지향 프로그래밍에서는 위의 두 예가 미묘하게 다르다고 생각할 수 있습니다. 그러나 JSX 엘리먼트는 내부 상태를 보유하지 않으며 실제 DOM 노드가 아니기 때문에 “인스턴스”가 아닙니다. 이것은 청사진처럼 간단한 설명입니다. 따라서 위의 두 가지 예시 코드는 실제로 완전히 동일합니다. 상태를 보존하고 초기화하기에서는 이 기능이 어떻게 작동하는지 자세히 설명합니다.
이제 완성된 항목의 텍스트를 <del>
과 같은 다른 HTML 태그로 줄 바꿈 하여 삭제하려고 합니다. 더 많은 JSX를 중첩하기 쉽도록 새로운 줄과 괄호를 추가할 수 있습니다.
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> ); }
이 스타일은 간단한 조건에 잘 어울리지만, 적당히 사용하는 게 좋습니다. 중첩된 조건부 마크업이 너무 많아 컴포넌트가 지저분해질 경우 자식 컴포넌트를 추출하여 정리하세요. React에서 마크업은 코드의 일부이므로 변수 및 함수와 같은 도구를 사용하여 복잡한 식을 정리할 수 있습니다.
논리 AND 연산자 (&&
)
또 다른 일반적인 손쉬운 방법은 JavaScript 논리 AND (’&&’) 연산자입니다. React 컴포넌트에서는 조건이 참일 때 일부 JSX를 렌더링하거나 그렇지 않으면 아무것도 렌더링하지 않을 때 를 나타내는 경우가 많습니다. 다음과 같이 &&
를 사용하면 isPacked
가 true
인 경우에만 조건부로 체크 표시를 렌더링할 수 있습니다.
return (
<li className="item">
{name} {isPacked && '✔'}
</li>
);
이것을 “isPacked
이면 (&&
) 체크 표시를 렌더링하고, 그렇지 않으면 아무것도 렌더링하지 않습니다.”라고 읽을 수 있습니다.
자, 잘 작동합니다.
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✔'} </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> ); }
JavaScript && 표현식은 왼쪽(조건)이 true
이면 오른쪽(체크 표시)의 값을 반환합니다. 그러나 조건이 false
이면 전체 표현 식이 false
가 됩니다. React는 false
를 null
또는 undefined
처럼 JSX 트리의 “구멍”으로 간주하고 그 자리에 아무것도 렌더링하지 않습니다.
변수에 조건부로 JSX를 할당하기
위와 같은 방법이 일반 코드를 작성하는 데 방해가 되면 if
문과 변수를 사용하세요. let
으로 정의된 변수는 재할당할 수 있으므로 표시할 기본 내용인 이름을 먼저 대입하세요.
let itemContent = name;
if
문을 사용하여 isPacked
가 true
인 경우 JSX 표현식을 itemContent
에 다시 할당합니다.
if (isPacked) {
itemContent = name + " ✔";
}
중괄호는 “JavaScript로 들어가는 창”을 엽니다. 반환된 JSX 트리에 중괄호를 사용하고 이전에 계산된 식을 JSX 내부에 중첩하여 변수를 포함합니다.
<li className="item">
{itemContent}
</li>
이 스타일은 가장 장황하면서도 가장 유연합니다. 코드가 잘 작동 중입니다.
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> ); }
이전과 같이 텍스트뿐만 아니라 임의의 JSX에도 작동합니다.
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = ( <del> {name + " ✔"} </del> ); } 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> ); }
JavaScript가 익숙하지 않다면, 처음에는 이런 다양한 코드 스타일이 낯설게 보일 수 있습니다. 그러나 이러한 코드를 학습한다면 React 컴포넌트뿐만 아니라 어떤 JavaScript 코드도 읽고 쓸 수 있습니다! 처음에 가장 선호하는 것을 선택해보고, 만약 다른 코드들이 어떻게 작동하는지를 잊어버린다면 이 문서를 다시 참고하세요.
Recap
- React에서 JavaScript로 분기 로직을 제어합니다.
- 조건부로
if
문과 함께 JSX 식을 반환할 수 있습니다. - 조건부로 일부 JSX를 변수에 저장한 다음 중괄호를 사용하여 다른 JSX에 포함할 수 있습니다.
- JSX에서
{cond ? <A /> : <B />}
는 “cond
이면<A />
를 렌더링하고, 그렇지 않으면<B />
를 렌더링합니다.” 를 의미합니다. - JSX에서
{cond && <A />}
는 “cond
이면,<A />
를 렌더링하되, 그렇지 않으면 아무것도 렌더링하지 않습니다.” 를 의미합니다. - 위 예시는 흔한 방법이지만,
if
를 선호한다면 사용하지 않아도 됩니다.
Challenge 1 of 3: ? :
를 사용하여 완료되지 않은 항목의 아이콘을 표시합니다.
isPacked
가 true
가 아닌 경우 조건부 연산자(cond ? a : b
)를 사용하여 ❌를 렌더링합니다.
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✔'} </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> ); }