Conditional Rendering
- Conditional Rendering
- 어떠한 조건(true/false)에 따라서 렌더링이 달라지는 것
예시
- 이미 회원인 사용자에게 보여줄 메시지를 출력할 UserGreeting 컴포넌트
function UserGreeting(props) {
return <h1>다시 오셨군요!</h1>;
}
- 아직 가입하지 않은 게스트 사용자에게 보여줄 메시지를 출력할 GuestGreeting 컴포넌트
function GuestGreeting(props) {
return <h1>회원가입을 해주세요.</h1>;
}
- 회원인지 아닌지에 따라 위 두 개의 컴포넌트를 선택적으로 보여주도록 조건부 렌더링을 사용하여 구현해보자.
- isLoggedIn이라는 변수 값이 true 이면 UserGreeting 컴포넌트를, 그렇지 않으면 GuestGreeting 컴포넌트를 리턴하도록 하면 된다.
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting/ >
}
return <GuestGreeting/ >
}
자바스크립트의 Truthy와 Falsy
- 보통 프로그래밍 언어에서는 참, 거짓을 구분하기 위해 Boolean 형태의 자료형이 존재하고, 그 값은 true와 false 둘 중 하나가 된다.
- 자바스크립트에서는 true는 아니지만 true로 여겨지는 값이 존재하는 데, 이것을 truthy라고 부른다.
- 마찬가지로 false는 아니지만 false로 여겨지는 값을 falsy라고 부른다.
- truthy
- true
- {} (empty object)
- [] (empty array)
- 42 (number, not zero)
- "0", "false" (string, not empty)
- falsy
- false
- 0, -0 (zero, minus zero)
- On (BigInt Zero)
- '', "", `` (empty string)
- null
- undefined
- NaN (not a number)
Element Variables
- Element Variables (엘리먼트 변수)
- 리액트 엘리먼트를 변수처럼 저장해서 사용하는 방법
예시
- 사용자의 로그인 여부에 따라 선택적으로 보여줄 로그인 버튼과 로그아웃 버튼
function LoginButton(props) {
return(
<button onClick={props.onClick}>
로그인
</button>
);
}
function LogoutButton(props) {
return(
<button onClick={props.onClick}>
로그아웃
</button>
);
}
- 두 개의 버튼을 로그인 여부에 따라 button이라는 변수에 컴포넌트를 대입하도록 엘리먼트 변수를 작성해보자.
function LoginControl(props) {
const [isLoggendIn, setIsLoggendIn] = useState(false);
const handleLoginClick = () => {
setIsLoggendIn(true);
}
const handleLogoutClick = () => {
setIsLoggendIn(false);
}
let button;
if (isLoggendIn) {
button = <LogoutButton onClick={handleLogoutClick} />;
} else {
button = <LoginButton onClick={handleLoginClick} />;
}
return (
<div>
<Greeting isLoggendIn={isLoggendIn} />
{button}
</div>
);
}
Inline Conditions
- 인라인 조건(Inline Conditions)
인라인 If
- if 문을 필요한 것에 직접 넣어서 사용하는 방법
- AND 논리 연산자
&&
사용
- 양쪽에 나오는 조건문에 모두 true인 경우에만 전체 결과가 true
- 단축 평가(Short-circuit evaluation)
- AND 연산 시 첫번째 조건문이 true 이면 두 번째 조건문 평가
- AND 연산 시 첫번째 조건문이 false이면 어차피 전체 결과가 false가 되므로 두 번째 조건문은 평가하지 않는다.
- 즉, 단축 평가에 의해 조건문이 true이면 오른쪽에 나오는 엘리먼트가 결괏값이 되고, false 이면 false가 결괏값이 된다.
true && expression -> expression
fasle && expression -> false
- 인라인 If는
&&
연산자를 JSX 코드 안에 중괄호를 사용하여 직접 넣어서 사용한다.
unreadMessages.length > 0
의 값에 따라 뒤에 나오는 <h2>
태그로 둘러싸인 부분이 렌더링이 되거나 안되게 하는 코드
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>안녕하세요!</h1>
{unreadMessages.length > 0 &&
<h2>
현재 {unreadMessages.length} 개의 읽지 않은 메시지가 있습니다.
</h2>
}
</div>
);
}
주의사항 !
&&
연산자를 사용할 때 조건문에 Falsy expression을 사용하면 뒤에 나오는 expression은 평가되지 않지만 Falsy expression의 결괏 값이 그대로 리턴된다.
- 예를 들어, 아래 코드에서는 화면에 아무것도 나오지 않는 것이 아니라 count의 값인 0이 들어가서
<div>0</div>
이 된다.
function Counter(props) {
const count = 0;
return (
<div>
{count && <h1>현재 카운트: {count}</h1>}
</div>
);
}
인라인 If-Else
- 조건문의 값에 따라 다른 엘리먼트를 보여줄 때 사용
- 삼항연산자
?
사용
?
앞에 나오는 조건문이 true일 경우 첫 번째 항목을 리턴하고, false일 경우 두번째 항목을 리턴
조건문 ? 참일 경우 : 거짓일 경우
- 실제 리액트에서 사용하는 형태는 다음과 같다.
- isLoggedIn의 값이 true인 경우 '로그인' 문자열을, false인 경우 '로그인 하지 않은' 문자열을 출력
function UserStatus(props) {
return (
<div>
이 사용자는 현재 <b>{props.isLoggedin ? '로그인' : '로그인하지 않은'}</b> 상태입니다.
</div>
);
}
- 아래 코드처럼 문자열이 아닌 엘리먼트를 넣어서 사용할 수도 있다.
- isLoggedIn 이 true인 경우 LogoutButton을, false인 경우 LoginButton을 출력
function LoginControl(props) {
const [isLoggendIn, setIsLoggendIn] = useState(false);
const handleLoginClick = () => {
setIsLoggendIn(true);
}
const handleLogoutClick = () => {
setIsLoggendIn(false);
}
return (
<div>
<Greeting isLoggendIn={isLoggendIn} />
{isLoggendIn
? <LogoutButton onClick={handleLogoutClick} />
: <LoginButton onClick={handleLoginClick} />}
</div>
);
}
컴포넌트 렌더링 막기
- 특정 컴포넌트를 렌더링하고 싶지 않을 때는
null
을 리턴하면 됨
- 리액트에서는
null
을 리턴하면 렌더링되지 않기 때문
예시
props.warining
값이 true인 경우에만 경고 메시지를 출력하고 false인 경우에는 아무것도 출력하지 않는 코드
function WarningBanner(props) {
if (!props.warning) {
return null;
}
return (
<div>경고!</div>
);
}
- 위에서 작성한 WarningBanner 컴포넌트를 실제로 사용해보자.
showWarning
이라는 state의 값을 WarningBanner
컴포넌트의 props로 전달하여 showWarning
의 값에 따라 경고문을 표시하거나 표시하지 않도록 작성
function MainPage(props) {
const [showWarning, setShowWarning] = useState(false);
const handleToggleClick = () => {
setShowWarning(prevShowWarning => !prevShowWarning);
}
return (
<div>
<WarningBanner warning={showWarning} />
<button onClick={handleToggleClick}>
{showWarning ? '감추기' : '보이기'}
</button>
</div>
)
}
실습 - 로그인 여부를 나타내는 툴바 만들기
- isLoggedIn(사용자의 로그인 여부) 값을 props로 받아 조건부 렌더링을 사용하여 환영 메시지를 표시하거나 감추고 로그인/로그아웃 버튼을 보여줌
&&
연산자와 ?
연산자 두 가지 방법을 이용하여 조건부 렌더링 구현
import React from "react";
const styles = {
wrapper: {
padding: 16,
display: "flex",
flexDirection: "row",
borderBottom: "1px solid grey",
},
greeting: {
marginRight: 8,
},
};
function Toolbar(props) {
const { isLoggedIn, onClickLogin, onClickLogout } = props;
return (
<div style={styles.wrapper}>
{isLoggedIn && <span style={styles.greeting}>환영합니다!</span>}
{isLoggedIn ? (
<button onClick={onClickLogout}>로그아웃</button>
) : (
<button onClick={onClickLogin}>로그인</button>
)}
</div>
);
}
export default Toolbar;
LandingPage 컴포넌트 작성
- useState() 훅을 사용해서 사용자의 로그인 여부를 관리
- 이 값을 Toolbar 컴포넌트에 전달하여 로그인 여부에 따라 툴바에 적절한 사용자 인터페이스가 표시되도록 함
import React, { useState } from "react";
import Toolbar from "./Toolbar";
function LandingPage(props) {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const onClickLogin = () => {
setIsLoggedIn(true);
};
const onClickLogout = () => {
setIsLoggedIn(false);
};
return (
<div>
<Toolbar
isLoggedIn={isLoggedIn}
onClickLogin={onClickLogin}
onClickLogout={onClickLogout}
/>
<div style={{ padding: 16 }}>소플과 함께하는 리액트 공부!</div>
</div>
);
}
export default LandingPage;
index.js 파일 수정
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import LandingPage from './chapter_09/LandingPage';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<LandingPage />
</React.StrictMode>
);
reportWebVitals();
실행 결과
- 초기 상태는 로그인이 되지 않은 상태이기 때문에 환영 메시지는 보이지 않으며 로그인 버튼이 표시됨
- 로그인 버튼을 누르면 로그인 상태가 바뀌면서 환영메시지와 로그아웃 버튼이 나오는 것을 볼 수 있음
실습 전체 코드
References