특정 값이 조건식에 따라서 엘리먼트를 보여주거나 안 보여줄 수 있다.
또는 이 엘리먼트를 보여주거나 저 엘리먼트를 보여줘야 할 때도 있다.
리액트에서는 이러한 조건부 렌더링을 어떻게 처리할까.
<body>
<div id="root1">
</div>
<div id="border1"></div>
<div id="root2">
</div>
<div id="border2"></div>
<div id="root3">
</div>
<div id="border3"></div>
<div id="root4">
</div>
<div id="border4"></div>
<div id="root5">
</div>
<div id="border5"></div>
<!-- react cdn -->
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<!-- react dom cdn -->
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<!-- babel cdn -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<!-- define type as a babel -->
<script type="text/babel">
class MakeBorder extends React.Component {
render() {
return <p>--------------------------------root{this.props.num}----------------------------</p>;
}
}
// 조건부 렌더링
// React에서 조건부 렌더링은 JavaScript에서의 조건 처리와 같이 동작한다.
// if나 조건부 연산자와 같은 JavaScript 연산자를 활용할 수 있다.
// 캡슐화하기
// React에서는 원하는 동작을 캡슐화하는 컴포넌트를 만들 수도 있다.
// 예를 들어 인사말을 출력하는 아래 두 컴포넌트를 보자.
function UserGreeting(props) {
return <h1>Welecome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
// 로그인 상태에 따라서 위 두 컴포넌트 중에 하나를 출력하고 싶다면 어떻게 해야 할까.
// 위 두 컴포넌트를 하위 컴포넌트로 가지는 상위 컴포넌트를 하나 더 만들고 그 안에 조건에 따라서 둘 중 하나를 출력하도록 보자.
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render( <Greeting isLoggedIn={false} />, document.getElementById('root1') );
ReactDOM.render( <MakeBorder num="1" />, document.getElementById('border1') );
// 리액트 요소를 변수에 넣기
// 리액트 요소를 변수에 저장할 수도 있다.
// 다른 부분은 그대로 둔 채로 컴포넌트의 일부분만 조건에 따라 렌더링할 수 있다.
// 예를 들어 로그인 또는 로그아웃 버튼을 나타내는 아래 두 컴포넌트를 보자.
function LoginButton(props) {
return (
<button onClick={props.onClick}>
Login
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
Logout
</button>
);
}
// 위 두 컴포넌트를 하위 컴포넌트로 갖는 상위 컴포넌트를 하나 만들어 보자.
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;
// button 이라는 이름으로 변수를 만들어 놓고, isLoggedIn 라는 값에 따라 다른 React 요소를 넣어 둔다.
// 출력할 때는 중괄호 {} 안에 변수명만 넣어주면 된다.
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('root2') );
ReactDOM.render( <MakeBorder num="2" />, document.getElementById('border2') );
// 논리 연산자 사용하기
// JSX 문법 안에서는 중괄호 {}를 활용해서 JavaScript 표현식을 사용할 수 있다.
// 논리 연산자 && 를 사용하면 조건에 따라 다르게 보여주는 기능을 쉽게 만들 수 있다.
// if( 조건식 ) { 출력할 요소 }
// 위 내용을 아래처럼 줄여서 표현할 수 있다.
// { 조건식 && React 요소 }
// 예를 들어 아래 컴포넌트를 보자.
// 이 컴포넌트는 리스트 안에 요소가 있을 때만 메세지를 출력한다.
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('root3') );
ReactDOM.render( <MakeBorder num="3" />, document.getElementById('border3') );
// JavaScript에서 true && expression은 항상 expression으로 평가되고 false && expression은 항상 false로 평가된다.
// 즉, 논리 연산자 && 뒤에 있는 표현식은, 논리 연산자 && 앞에 있는 조건식에 따라서 출력되거나 출력되지 않는다.
// 단, falsy 표현식을 반환하면 여전히 && 뒤에 있는 표현식은 건너뛰지만 falsy 표현식이 반환된다는 점에 유의하자.
// 예를 들어 아래에서는 <div>0</div> 가 출력된다.
// render() {
// const count = 0;
// return (
// <div>
// {count && <h1>Messages: {count}</h1>}
// </div>
// );
// }
// 삼항연산자를 사용하여 If-Else구문 인라인으로 표현하기
// 조건에 따라 리액트 요소를 나타내거나 나타내지 않는 방법을 알아보고 있다.
// 앞에서는 중관호 {} 안에 논리 연사자 && 를 활용하여 요소가 출력될지 여부를 결정했다.
// 비슷한 방법으로 삼항 연사자 condition ? true: false 를 활용하는 방법도 있다.
// 내용이 앞과 비슷하고 어렵지 않으므로 예시만 보고 넘어가자.
// 아래는 isLoggedIn 에 따라서 메세지 내용이 바뀐다.
// 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이라는 props 값에 따라서 렌더링된다.
// 만약 warn이 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('root4') );
ReactDOM.render( <MakeBorder num="4" />, document.getElementById('border4') );
</script>
</body>
- 220529
참고자료 -
반응형
'React' 카테고리의 다른 글
React 시작하기 - 09 - textarea, input, select 등 폼 form 태그 다루기 (0) | 2022.06.18 |
---|---|
React 시작하기 - 08 - 리스트 반복문으로 엘리먼트 만들기, key 개념 (0) | 2022.06.18 |
React 시작하기 - 06 - 이벤트 핸들링하기, this 바인딩 해주기, e 합성 이벤트 (0) | 2022.06.18 |
React 시작하기 - 05 - 컴포넌트 안에서 state와 생명 주기 활용하기 (0) | 2022.06.18 |
React 시작하기 - 04 - 클래스 컴포넌트, 함수 컴포넌트, props 주고받기 (0) | 2022.06.18 |