안녕하세요! 조건부렌더링에 관한 포스팅입니다.
리액트로 컴포넌트를 만들다보면 props나 state에 따라 달라지는 컴포넌트를 반환하고 싶을 때가 있습니다.
조건부렌더링을 깔끔하게 작성하면, 코드의 가독성이 높아집니다.
이런 폼을 만들어볼게요
나이가 14세 미만일경우 "14세 미만은 부모님 동의가 필요합니다. 라는 메세지를 출력하고, 14세 이상일 경우 "다음단계로 진행해주세요" 메세지를 출력합니다.
조건1 14세이상일 경우
조건2 14세 미만일 경우
조건부렌더링을 작성하는 방법들
부모컴포넌트 MyComponent
자식컴포넌트 Message에 key값을 줘서 완전비제어컴포넌트로 작성했습니다.
import React from 'react'
import Message from "./Message";
export default class MyComponent extends React.Component {
state = {
name : '',
age : ''
}
handleNameChange = (e) => {
const name = e.target.value;
this.setState({name})
}
handleAgeChange = (e) => {
const age = e.target.value;
this.setState({age})
}
render () {
return (
<div>
name : <input type='text' onChange={this.handleNameChange} value={this.state.name}></input><br/>
age : <input type='text' onChange={this.handleAgeChange} value={this.state.age}></input><br/>
<button onClick={()=>{console.log(this.state)}}> NEXT </button>
<Message name={this.state.name} age={this.state.age} key={this.state.age}></Message>
</div>
)
}
}
Message컴포넌트 조건부렌더링
if를 사용한 자식컴포넌트 Message
import React from 'react'
export default class Message extends React.Component {
render () {
if(this.props.age >= 14) {
return <p>{`다음 단계로 진행해주세요`}</p>
}else {
return <p>{`14세 미만은 부모님 동의가 필요합니다.`}</p>
}
}
}
import React from 'react'
export default class Message extends React.Component {
render () {
const {age} = this.props;
return age >= 14? (<p>{`다음 단계로 진행해주세요`}</p>) : (<p>{`14세 미만은 부모님 동의가 필요합니다.`}</p>)
}
}
import React from 'react'
export default class Message extends React.Component {
state = {
overFourteenYearsOld : this.props.age >= 14
}
render () {
const {overFourteenYearsOld} = this.state;
return (
<React.Fragment>
{overFourteenYearsOld && <p>다음 단계로 진행해주세요.</p>}
{!overFourteenYearsOld && <p> 14세 미만은 부모님 동의가 필요합니다. </p>}
</React.Fragment>
)
}
}
&& 연산자를 사용하면 조건도 한 눈에 들어오고, 그룹이 두 개라는 것도 쉽게 알 수 있습니다.
&& 연산자를 사용할 때 주의할 점
&&연산자는 가독성이 좋지만, 주의할 점이 있습니다.
0일 경우에는 거짓으로 판단해 의도한대로 렌더링 되지 않을 수 있습니다.
<div>
{cash && <p>{cash}원 보유중</p>}
</div>
cash가 0원일 경우 0원 보유 중 을 출력해야 하는데 출력되지 않습니다. 숫자 0이 출력되는데, &&연산자가 마지막으로 검사한 값이 0이기 때문입니다. 0일 경우 출력하고싶지 않다면 !!cash&& 를 입력합니다.
<div>
{memo && <p> {200 - memo.length}자 입력가능</p>}
</div>
다음 경우 memo가 빈 문자열일 때 200자 입력가능이 출력되어야 합니다. 하지만, 이 경우에도 출력되지 않습니다.
이런 경우에는 명확하게 undefined, null이 아닌 경우라고 표현해야 합니다.
잘 동작하는 경우
<div>
{cash !== null && <p> {cash}원 보유 중 </p>}
{memo !== undefined && <p> {200 - memo.length}자 입력가능 </p>
</div>
변수가 배열인 경우 기본값을 빈 배열을 넣어주는게 좋습니다.
<div>{arr1 && arr1.map(elem => /**/ )}<div/>
<div>{arr2.map(elem=> /**/)} <div/>
배열을 기본값으로 사용하면 추가적인 판별이 필요없어 코드가 더 간결해집니다.
조건부렌더링을 간결하게 작성하는 방법을 살펴봤습니다. 어느 것이 제일 좋다고 하기 어렵지만, 상황에 따라 잘 선택해야겠습니다.