조건부 렌더링
우리는 핵심 개념인 컴포넌트, props
, state
, 그리고 이벤트 처리를 학습했습니다. 이제 이러한 기초 지식을 바탕으로 더욱 복잡하고 동적인 UI를 구현하는 방법을 알아볼 차례입니다.
이번 장에서는 조건부 렌더링(Conditional Rendering) 에 대해 다룰 것입니다. 조건부 렌더링은 특정 조건이 만족될 때만 컴포넌트나 UI 요소를 화면에 보여주거나, 또는 다른 컴포넌트를 보여주는 기법을 의미합니다. 예를 들어, 사용자가 로그인했을 때만 '마이 페이지' 버튼을 보여주거나, 로딩 중일 때는 '로딩 스피너'를 보여주는 것 등이 모두 조건부 렌더링의 예시입니다.
리액트에서 조건부 렌더링을 구현하는 방법은 여러 가지가 있으며, 상황에 따라 적절한 방법을 선택하는 것이 중요합니다.
if
문 (조건문) 사용하기
가장 기본적인 조건부 렌더링 방법은 자바스크립트의 if
문을 사용하는 것입니다. if
문은 컴포넌트의 return
문 바깥에서 조건을 검사하고, 그 결과에 따라 다른 JSX를 반환하도록 할 때 유용합니다.
예제: 로그인 상태에 따른 메시지 표시
-
LoginControl.js
컴포넌트 생성:src/components
폴더 안에LoginControl.js
파일을 생성합니다.src/components/LoginControl.js // src/components/LoginControl.js import React, { useState } from 'react'; function GuestGreeting() { return <h2>로그인 해주세요!</h2>; } function UserGreeting(props) { return <h2>환영합니다, {props.userName}님!</h2>; } function LoginButton(props) { return ( <button onClick={props.onClick}> 로그인 </button> ); } function LogoutButton(props) { return ( <button onClick={props.onClick}> 로그아웃 </button> ); } function LoginControl() { const [isLoggedIn, setIsLoggedIn] = useState(false); const [userName, setUserName] = useState(''); // 로그인 시 사용자 이름 저장 const handleLoginClick = () => { setIsLoggedIn(true); setUserName('김코딩'); // 예시 사용자 이름 설정 }; const handleLogoutClick = () => { setIsLoggedIn(false); setUserName(''); }; let button; // (1) 조건에 따라 렌더링할 버튼 변수 선언 if (isLoggedIn) { // (2) if 문을 사용하여 조건 검사 button = <LogoutButton onClick={handleLogoutClick} />; } else { button = <LoginButton onClick={handleLoginClick} />; } let greeting; // (3) 조건에 따라 렌더링할 인사말 변수 선언 if (isLoggedIn) { greeting = <UserGreeting userName={userName} />; } else { greeting = <GuestGreeting />; } return ( <div style={{ border: '1px solid #0056b3', padding: '20px', margin: '20px', borderRadius: '8px', textAlign: 'center' }}> {greeting} {/* (4) JSX 내에서 변수 사용 */} {button} </div> ); } export default LoginControl;
isLoggedIn
state
에 따라 다른greeting
컴포넌트(GuestGreeting
또는UserGreeting
)와 다른button
컴포넌트(LoginButton
또는LogoutButton
)를 할당합니다.return
문 안에서는 이 변수들을{}
중괄호 안에 넣어 렌더링합니다.
-
App.js
에서LoginControl
컴포넌트 사용:src/App.js // src/App.js import React from 'react'; import './App.css'; import LoginControl from './components/LoginControl'; // LoginControl 컴포넌트 불러오기 function App() { return ( <div className="App"> <h1>React 조건부 렌더링 예시</h1> <LoginControl /> </div> ); } export default App;
-
결과 확인: 브라우저에서 로그인/로그아웃 버튼을 클릭해 보세요. 메시지와 버튼이 로그인 상태에 따라 변경되는 것을 볼 수 있을 것입니다.
if
문은 여러 컴포넌트를 반환해야 하거나, 조건이 복잡하여 가독성을 높여야 할 때 유용합니다.
인라인 조건부 렌더링 (삼항 연산자 ? :
)
JSX 내부에서 간단하게 조건을 처리하고 싶을 때는 삼항 연산자(condition ? true : false
) 를 사용할 수 있습니다. 이는 if
문보다 간결하게 조건을 표현할 수 있어 자주 사용됩니다.
예제: MessageChanger
컴포넌트를 삼항 연산자로 리팩토링
이전 장에서 만들었던 MessageChanger
컴포넌트를 삼항 연산자로 조건부 렌더링을 적용하여 수정해 보겠습니다.
// src/components/MessageChanger.js (수정)
import React, { useState } from 'react';
function MessageChanger() {
const [showMessage, setShowMessage] = useState(false); // 메시지 표시 여부 상태
const handleToggleMessage = () => {
setShowMessage(!showMessage); // 상태 반전
};
return (
<div style={{ border: '1px dashed #999', padding: '15px', margin: '20px', borderRadius: '8px' }}>
<h2>메시지 토글</h2>
{/* showMessage가 true이면 메시지를 보여주고, false이면 아무것도 보여주지 않음 */}
{showMessage ? ( // (1) 삼항 연산자 사용
<p style={{ fontSize: '20px', fontWeight: 'bold', color: '#28a745' }}>
지금 메시지가 보입니다!
</p>
) : (
<p style={{ fontSize: '16px', color: '#6c757d' }}>
메시지가 숨겨져 있습니다.
</p>
)}
<button onClick={handleToggleMessage} style={{ padding: '10px 20px', fontSize: '16px', cursor: 'pointer' }}>
{showMessage ? '메시지 숨기기' : '메시지 보기'} {/* 버튼 텍스트도 조건부 렌더링 */}
</button>
</div>
);
}
export default MessageChanger;
showMessage
state
의 값에 따라 다른<p>
태그가 렌더링됩니다.- 버튼의 텍스트도
showMessage
값에 따라 "메시지 숨기기" 또는 "메시지 보기"로 변경됩니다.
삼항 연산자는 조건이 간단하고, 참
과 거짓
두 가지 경우 중 하나를 렌더링할 때 매우 효과적입니다.
논리 연산자 &&
(AND) 사용하기
특정 조건이 참(True)일 때만 어떤 요소를 렌더링하고, 거짓일 때는 아무것도 렌더링하지 않고 싶을 때 논리 AND(&&
) 연산자를 사용할 수 있습니다.
리액트에서 JSX가 반환될 수 있는 값 중 null
, false
, undefined
는 화면에 렌더링되지 않는다는 특성을 이용한 것입니다. true && expression
은 expression
으로 평가되고, false && expression
은 false
로 평가됩니다.
예제: 경고 메시지 표시/숨기기
// src/components/WarningBanner.js
import React, { useState } from 'react';
function WarningBanner({ warn }) { // warn props를 받음
if (!warn) { // warn이 false면 null을 반환하여 아무것도 렌더링하지 않음
return null;
}
return (
<div style={{ backgroundColor: '#ffc107', color: 'white', padding: '10px', borderRadius: '5px', marginBottom: '15px' }}>
경고! 데이터가 안전하지 않습니다.
</div>
);
}
function AlertControl() {
const [showWarning, setShowWarning] = useState(true);
const handleToggleClick = () => {
setShowWarning(prevWarn => !prevWarn);
};
return (
<div style={{ border: '1px solid #dc3545', padding: '20px', margin: '20px', borderRadius: '8px', textAlign: 'center' }}>
<h2>경고 배너 제어</h2>
{/* showWarning이 true일 때만 WarningBanner 컴포넌트가 렌더링됨 */}
{showWarning && <WarningBanner warn={true} />} {/* (1) 논리 AND 연산자 사용 */}
<button onClick={handleToggleClick} style={{ padding: '10px 20px', fontSize: '16px', cursor: 'pointer' }}>
{showWarning ? '경고 숨기기' : '경고 보이기'}
</button>
</div>
);
}
export default AlertControl;
showWarning && <WarningBanner warn={true} />
:showWarning
이true
일 때만<WarningBanner>
컴포넌트가 렌더링되고,false
일 때는 아무것도 렌더링되지 않습니다.
&&
연산자는 특정 조건이 만족할 때만 UI 요소를 보여주고, 그렇지 않을 때는 단순히 숨기고 싶을 때 매우 간결하게 사용할 수 있습니다.
컴포넌트 렌더링 막기: null
반환
드물지만, 컴포넌트가 렌더링되는 것을 완전히 막고 싶을 때가 있습니다. 이럴 때는 컴포넌트의 return
문에서 null
을 반환하면 됩니다. 리액트는 null
이 반환되면 해당 컴포넌트를 렌더링하지 않습니다.
위 WarningBanner
컴포넌트에서 이미 이 방법을 사용했습니다.
function WarningBanner({ warn }) {
if (!warn) { // warn이 false면
return null; // 아무것도 렌더링하지 않음
}
// ... (JSX 렌더링 코드)
}
null
을 반환하는 것은 컴포넌트의 렌더링 출력을 완전히 숨기는 효과가 있습니다.
조건부 렌더링 방법 선택 가이드
어떤 조건부 렌더링 방법을 선택할지는 상황과 개인의 선호도에 따라 달라질 수 있습니다.
if
문- 조건이 복잡하거나, 조건에 따라 완전히 다른 여러 개의 JSX 블록을 렌더링해야 할 때.
- 함수형 컴포넌트의
return
문 바깥에서 로직을 분리하여 가독성을 높이고 싶을 때.
- 삼항 연산자 (
? :
)참
일 때와거짓
일 때 모두 렌더링해야 하는 내용이 있고, 비교적 간결한 JSX를 반환할 때.- JSX 내부에서 인라인으로 조건을 표현하기 가장 적합합니다.
- 논리 AND 연산자 (
&&
)- 조건이
참
일 때만 특정 요소를 렌더링하고,거짓
일 때는 아무것도 렌더링하지 않을 때. - 매우 간결하게 한 줄로 표현할 수 있습니다.
- 조건이
null
반환- 특정 조건에서 컴포넌트 자체를 렌더링하지 않고 싶을 때.
이러한 다양한 방법들을 적절히 활용하여 여러분의 리액트 컴포넌트를 더욱 유연하고 동적으로 만들어나갈 수 있습니다. 다음 장에서는 리액트 컴포넌트의 또 다른 중요한 개념인 '리스트 렌더링'에 대해 학습하겠습니다.
3장 1절 "조건부 렌더링"은 여기까지입니다. if
문, 삼항 연산자, 논리 AND 연산자, null
반환 등 다양한 조건부 렌더링 기법들을 예제와 함께 자세히 설명했습니다. 각 방법의 특징과 사용 시기를 제시하여 독자들이 상황에 맞게 선택할 수 있도록 했습니다.