이 포스팅은 https://reactjs.org/docs/conditional-rendering.html 에 있는 포스팅을 번역한 것입니다. 오역이나 의역이 있을 수 있습니다. 지적해주시면 확인 후 바로 정정하겠습니다.
original source of this posting is from https://reactjs.org/docs/conditional-rendering.html If the original author requests deletion, it will be deleted immediately.
Translated by Jake Seo (서진규)
- https://velog.io/@jakeseo_me
- https://github.com/n00nietzsche
리액트 공식문서로 배워보자 #7, 조건부 렌더링!
리액트에서는, 필요한 동작을 캡슐화하는 독립적인 컴포넌트를 만들 수 있습니다. 또, 어플리케이션의 state에 따라 그들 중 오직 몇몇개만 렌더링 할 수도 있습니다.
리액트에서 조건부 렌더링은 자바스크립트 내부의 조건문과 똑같이 동작합니다. 현재 상태를 나타내는 엘리먼트를 만들기 위해서 자바스크립트 if와 같은 연산자들 또는 조건부 연산자를 사용하세요. 그리고 리액트가 그 상태에 맞춰 UI를 업데이트하게 두면 됩니다.
다음 두개의 컴포넌트를 생각해봅시다.
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
우리는 유저가 로그인했는지 아닌지에 따라 위의 2가지 상태 중 1가지를 보여주는 Greeting
컴포넌트를 만들 것입니다.
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의 값에 따라 다른 인사를 렌더링합니다.
엘리먼트를 저장하기 위해서 변수를 사용할 수 있습니다. 이 기능은 나머지 출력 결과물이 변경되지 않는 동안, 컴포넌트의 일부를 렌더링하는 것을 돕습니다.
로그인과 로그아웃을 보여주는 다음 두개의 버튼을 생각해봅시다.
function LoginButton(props) {
return (
<button onClick={props.onClick}>
Login
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
Logout
</button>
);
}
아래의 예제에서, 우리는 LoginControl
이라 불리는 상태가 있는 컴포넌트를 만들 것입니다.
이 컴포넌트는 <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;
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')
);
{}
괄호로 감싸, JSX에서 어떤 표현식을 삽입할 수도 있습니다. 이 방법은 자바스크립트의 논리적 &&
연산자를 포함합니다. 조건부로 엘리먼트를 포함할 때 매우 편리합니다.
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 && expression
은 언제나 false
이기 때문입니다.
그러므로 조건이 true
일 때는, &&
오른쪽 옆에 있는 엘리먼트는 출력됩니다. 만일 조건이 false
라면 리액트는 무시하고 넘어갑니다.
엘리먼트를 조건부로 렌더링하기 위해 사용되는 또다른 메소드는 자바스크립트의 조건부 연산자 condition ? true : false를 이용하는 것입니다.
아래 예제에서, 우리는 텍스트의 작은 블록을 조건부로 렌더링하기 위해 이 문법을 사용할 겁니다.
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
</div>
);
}
가독성은 떨어지지만, 더 큰 표현식에 대해서도 사용될 수 있습니다.
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? (
<LogoutButton onClick={this.handleLogoutClick} />
) : (
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
);
}
자바스크립트처럼 단순히 여러분과 여러분의 팀이 생각하기에 무엇이 더 가독성이 좋은지 판단하여 적절한 스타일을 사용하시면 됩니다. 또한 조건이 너무 복잡해질 때는, 컴포넌트 추출을 하는 것이 바람직하다는 것을 기억해두세요.
아주 드물게, 어떤 컴포넌트가 다른 컴포넌트에 의해 렌더링됐지만 그걸 숨기고 싶을 때가 있습니다. 이렇게 하기 위해, 렌더링을 하는 대신에 그냥 null
을 리턴하세요.
아래 예제에서, <WarningBanner />
는 warn
이라는 prop 값에 의해 렌더링이 결정됩니다. 만일 prop의 값이 false
라면, 컴포넌트는 렌더링되지 않습니다.
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(state => ({
showWarning: !state.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')
);
컴포넌트의 render
메소드로부터 null
을 반환하는 것은 컴포넌트의 라이프사이클 메소드를 동작시키는데는 아무런 영향을 주지 않습니다. 예를 들면, componentDidUpdate
메소드는 여전히 잘 실행될 것입니다.