Conditional Rendering
React에서는 필요한 기능을 캡슐화한 고유한 컴포넌트를 만들 수 있다. 그리고 애플리케이션의 상태에 따라 이들 중
일부만 렌더링할 수 있다.
React에서의 조건부 렌더링은 자바스크립트에서 조건문이 하는 방식과 동일하게 작동한다. 자바스크립트의 if나
조건 연산자같은 연사자들을 이용하여 현재 상태를 표시할 elements를 생성할 수도 있고, React가 거기에 맞춰
UI를 업데이트하도록 할 수도 있다.
아래의 두 component를 살펴보자
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
사용자가 로그인 했는지의 여부에 따라 이들 중 하나의 component를 표시하는 Greeting
이라는 component를
만들 수 있을 것이다.
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render(
// Try changing to isLoggedIn={true}:
<Greeting isLoggedIn={false} />,
document.getElementById('root')
);
이 예제는 isLoggedIn
이라는 prop의 값에 따라 다른 greeting을 렌더링 한다.
Element Variables
elements를 저장하기 위해 변수들을 사용할 수 있다. 이렇게 할 경우 출력의 나머지 부분이 변경되지 않고 있는 상태에서
일부 component를 조건부로 렌더링 하는데 도움이 된다.
로그인 버튼과 로그아웃 버튼을 표시하는 새로운 두 개의 component를 살펴보자
function LoginButton(props) {
return (
<button onClick={props.onClick}>
Login
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
Logout
</button>
);
}
이 component들 아래에 LoginControl
이라는 상태를 갖는 component를 만들 것이다.
이 component는 자신의 현재 상태에 따라 <LoginButton />
또는 <LogoutButton />
를 렌더링 할 것이다.
또한 이전 예제에서 보았던 <Greeting />
도 렌더링 할 것이다.
class LoginControl extends React.Component {
constructor(props) {
super(props);
this.handleLoginClick = this.handleLoginClick.bind(this);
this.handleLogoutClick = this.handleLogoutClick.bind(this);
this.state = {isLoggedIn: false};
}
handleLoginClick() {
this.setState({isLoggedIn: true});
}
handleLogoutClick() {
this.setState({isLoggedIn: false});
}
render() {
const isLoggedIn = this.state.isLoggedIn;
let button = null;
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
);
}
}
ReactDOM.render(
<LoginControl />,
document.getElementById('root')
);
변수를 선언하고 if
문을 사용하는 것은 component를 조건부로 렌더링하는 좋은 방법이며, 때때로 더 짧은
문법을 사용하는 것이 더 좋을 것이다. JSX에는 몇가지 inline 조건 처리 방법이 있는데 아래에서 설명할 것이다.
Inline If with Logical && Operator
중괄호({})를 사용함으로써 JSX의 어떤 표현식들을 내장시킬 수 있다. 여기에는 자바스크립트의 논리 연산자인&&
이 포함된다. 이 연산자를 사용하는 것이 조건부로 element를 포함시키는데 더 편한 경우도 있다.
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
);
}
const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
<Mailbox unreadMessages={messages} />,
document.getElementById('root')
);
이 예제는 자바스크립트 내에서 실행되기 때문에 true && expression
은 항상 expression의 값을 갖게 되며false && experssion
은 항상 false의 값을 갖게 된다.
그러므로 만일 조건이 true
라면 &&
오른쪽의 element가 출력으로 표시된다. 반면에 조건이 false
라면
React는 이 문장을 무시하고 건너 뛸 것이다.
Inline If-Else with Conditional Operator
elements를 inline으로 조건부 렌더링하는 방법에는 자바스크립트의 조건 연산자인 condition ? true : false
를
사용하는 방법도 있다.
아래의 예제에서 작은 텍스트 블록을 렌더링 하기 위해 이 방법을 사용할 것이다.
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
</div>
);
}
It can also be used for larger expressions although it is less obvious what's going on:
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? (
<LogoutButton onClick={this.handleLogoutClick} />
) : (
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
);
}
자바스크립트에서와 마찬가지로 어떤 것이 더 가독성이 좋은가 하는 선택은 당신에게 달려있다. 또한 조건이 더 복잡해
진다는 것은 component를 분리하기에 좋은 시점이란 것을 명심하자.
Preventing Component from Rendering
아주 드문 경우로 어떤 component가 다른 component로부터 렌더링 되었음에도 불구하고 숨겨야 할 경우가 있다.
이런 경우 렌더링될 출력값 대신 null
을 리턴하면 된다.
아래의 예제에서 <WarningBanner />
는 warn
이라는 prop의 값에 따라 렌더링이 결정된다. 만일 prop의 값이false
라면 component는 렌더링되지 않는다.
function WarningBanner(props) {
if (!props.warn) {
return null;
}
return (
<div className="warning">
Warning!
</div>
);
}
class Page extends React.Component {
constructor(props) {
super(props);
this.state = {showWarning: true}
this.handleToggleClick = this.handleToggleClick.bind(this);
}
handleToggleClick() {
this.setState(prevState => ({
showWarning: !prevState.showWarning
}));
}
render() {
return (
<div>
<WarningBanner warn={this.state.showWarning} />
<button onClick={this.handleToggleClick}>
{this.state.showWarning ? 'Hide' : 'Show'}
</button>
</div>
);
}
}
ReactDOM.render(
<Page />,
document.getElementById('root')
);
component로부터 null
을 리턴받게 되는 경우 render
메소드는 component의 lifecycle 메소드들을
작동시키지 않는다. 하지만 componentWillUpdate
와 componentDidUpdate
는 여전히 호출된다.
'Study > React' 카테고리의 다른 글
React 살펴보기 #7 (0) | 2017.04.20 |
---|---|
React 살펴보기 #6 (0) | 2017.03.27 |
React 살펴보기 #5 (0) | 2017.03.04 |
React 살펴보기 #4 (0) | 2017.02.17 |
React 살펴보기 #3 (0) | 2017.02.11 |