조건부 렌더링.
어떤 조건에 따라 렌더링 결과가 달라지는 방식
예제
// 이미 회원인 유저에게 보여줄 컴포넌트
function UserGreeting(props) {
return <h1>다시 오셨군요!</h1>;
}
// 아직 회원이 아닌 유저에게 보여줄 컴포넌트
function GuestGreeting(props) {
return <h1>회원가입을 해주세요.</h1>
}
// 로그인 여부에 따라 다른 컴포넌트를 보여줌
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GestGreeting />;
}
JS에선 기본적으로 boolean 자료형을 써서 true/false를 구분할 수 있다. 그럼, Truthy/Falsy는 각각
Truthy/Falsy는 각각
true/false는 아니지만, true/false로 여겨지는 값이다.
예제
// truthy
true // 일반 true
{}, [] // 비어있는 object, array
42 // 0이 아닌 숫자
"0", "false" // 비어있지 않은 문자열
// falsy
false // 일반 false
0, -0 // 숫자 0
0n // BigInt Zero
'', "", `` // 비어있는 문자열
null
undefined
NaN // Not a Number
조건부 렌더링을 사용하다 보면 Element를 변수처럼 사용하고 싶을 경우가 있는데, 그런 경우에 상용한다.
예제
function LoginButton(props) {
return (
<button onClick={props.onClick}>
로그인
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
로그아웃
</button>
);
}
function LoginControl(props) {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const handleLoginClick = () => {
setIsLoggedIn(true);
};
const handleLogoutClick = () => {
setIsLoggedIn(false);
}
let button = isLoggedIn
? <LogoutButton onClcik={handleLogoutClick} />
: <LoginButton onClick={handleLoginClick} />;
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
);
}
'&&'는 논리 연산자로서 앞의 조건문과 뒤의 조건문이 모두 true여야 true를 반환한다. React에선 여기서 더 나아가, 앞의 조건문이 true인 경우엔 뒤의 expression을 반환하고 false인 경우엔 그냥 false를 반환한다.
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>안녕하세요!</h1>
{unreadMessages.length > 0 &&
<h2>
현재 {unreadMessages.length}개의 읽지 않은 메시지가 있습니다
</h2>
}
</div>
);
}
위의 예제에선 unreadMessages.length가 0 이하이면 false를 반환한다. 때문에 빈 값을 넣고 싶더라도 결과적으론 "false"가 DOM에 렌더링된다.
이런 문제를 해결하기 위해 삼항 연산자를 사용한다.
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>안녕하세요!</h1>
{unreadMessages.length > 0
? <h2>현재 {unreadMessages.length}개의 읽지 않은 메시지가 있습니다</h2>
: null // null을 리턴하면, 아무것도 출력하지 않는다.
}
</div>
);
}