React에서는 필요한 동작을하는 캡슐화된 고유 한 컴포넌트를 만들 수 있습니다. 그런 다음 응용 프로그램의 state에 따라 일부만 렌더링 할 수 있습니다.
React의 조건부 렌더링은 JavaScript가 동작하는 것과 같은 방식으로 동작합니다. if
또는 조건 연산자와 같은 자바 스크립트 연산자를 사용하여 현재 state를 나타내는 요소를 만들고 React가 UI를 업데이트하여 일치 시킵니다.
두 컴포넌트를 살펴봅시다.
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
사용자의 로그인 여부에 따라 위 컴포넌트 중 하나를 표시하는 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')
);
위 예제는 props
isLoggedIn
값에 따라 다른 인사말 컴포넌트를 렌더링합니다 .
변수를 사용하여 요소를 저장할 수 있습니다. 이렇게 하면 컴포넌트의 일부를 조건부로 렌더링하는 데 도움이 되며 나머지 출력은 변경되지 않습니다.
로그 아웃 및 로그인 버튼을 나타내는 다음 두 개의 새로운 컴포넌트를 살펴보겠습니다.
function LoginButton(props) {
return (
<button onClick={props.onClick}>
Login
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
Logout
</button>
);
}
위 예제에서, LoginControl
이라는 state를 가진 컴포넌트 를 생성했습니다.
이 컴포넌트는 현재 상태에 따라 <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')
);
변수를 선언하고 if
문을 사용하는 것은 조건부로 구성 요소를 렌더링하는 좋은 방법이지만, 짧은 구문을 사용하고 싶은 경우가 있습니다. 아래에 예시로 JSX
를 이용하여 인라인으로 조건을 처리하는 몇 가지 방법이 있습니다.
중괄호로 감싸면 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
라면, React는 이를 무시하고 건너뜁니다.
인라인으로 요소를 조건부 렌더링하는 다른 방법은 자바스크립트의 조건부 연산자인 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
을 반환하면 컴포넌트의 라이프사이클 메서드가 구동하지 않습니다. 대신, componentWillUpdate
와 componentDidUpdate
는 여전히 호출됩니다.