Conditional Rendering for React

리액트에서는 조건부 렌더링을 사용하기 위한 방법으로 아래와 같은 방식을 제시하고 있다.

요약하자면,

컴포넌트 자체 처리

<Component show={condition} />

inline if

{condition && <Component />}

삼항연산자

{condition ? <Component /> : null or other component}

변수로 담아두기

let component;
if (condition) {component = <Component />}
else {component = null}
{component}

함수로 담아두기

renderComponent() {
if (condition) {
return <Component />
}
return null
}
{this.renderComponent()}

하지만 이와 다르게 조건문을 처리해보고자 하는 시도들이 여럿 있었다. 이 글에서는 이런 방법들을 한 번 소개해보고자 한다.

<If cond={}>

// Example Code from react-if
class Beer extends React.Component {
render() {
return (
<div>
<If condition={ this.props.age >= 16 }>
<Then>Have a beer, {this.props.name}!</Then>
<Else>{() => // will only be evaluated if the condition fails.
<span>Sorry, {this.props.name}, you are not old enough.</span>
}</Else>
</If>
</div>
);
}
}

혹은 컴포넌트가 아닌 Babel에 처리를 맡겨버리는 방식도 있다.

이런 방법을 찾아보던 중, 나에게는 굳이 If Then Else 문법까지 필요할 것 같지 않아서 직접 구현해보기로 했다. 생각보다 간단한 코드다.

여기에서 If의 children을 function으로 반-강제하는 것은, function이 아닌 컴포넌트의 형태로 자식 컴포넌트를 표현할 경우, 조건의 참 여부와 관계없이 자식 컴포넌트를 만들어내는 코드가 실행되어 평가되기 때문이다. 쉬운 코드로 풀어 쓰자면,

// If의 children이 컴포넌트일 경우
let trueResult = React.createElement(Component) // condition에 상관없이 실행됨
let falseResult = null
if (condition) {
return trueResult
} else {
return falseResult
}
// If의 children이 함수일 경우
if (condition) {
return getTrueResult() // condition == true일 때에만 실행됨
} else {
return null
}

한편, 이렇게 <If> 컴포넌트를 만들어 사용하는 일이 굉장히 React에 적합하다고 생각해 신나게 사용하던 차에, 이 컴포넌트의 몇 가지 단점을 발견했다.

  • If 역시 컴포넌트다. 컴포넌트는 단 하나의 Root 엘리먼트를 가져야 한다. 즉, 아래와 같은 형식은 If로 대체할 수 없다.
{condition ? [<Comp1 key={1} />, <Comp2 key={2} />] : null}
  • If의 children이 function이기 때문에, children에 대한 validation이 어렵다.
  • CSSTransitionGroup과 같이 컴포넌트 렌더링에 관여하는 역할을 가진 라이브러리와의 궁합이 잘 맞지 않는다.

더 많은 논의는 아래 링크에서 확인할 수 있다.

결론

하지만 나는 계속해서 <If>를 사용하기로 했다. 일단, 기존에 제시된 방법들이 어떻게 보아도 JSX 속에서 깔끔해보이지 않았던 것이 첫 번째 이유이다. 다른 이유로는, <If>를 사용하면 JSX에서 {} 내부에 작성되는 대부분의 코드를 텍스트 노드로 제한할 수 있다. 하나의 컨벤션이 될 수 있는 것이다.

하지만 단서 조항을 하나쯤 달아두기로 했다. 경우의 수가 4가지 이상 되어 switch문이 더 간편한 경우나, <If> 내부에 10줄 이상의 코드가 필요할 경우 {this.renderSomething()}으로 분리하고 이 분리된 함수 내부에서 분기를 처리하는 방식을 사용하기로 했다.

--

--

--

Frontend Developer, mainly using React.js

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
HyeonSeok Yang

HyeonSeok Yang

Frontend Developer, mainly using React.js

More from Medium

How to Reset React Context

React context code snippet

How To Create A NetworkErrorBoundary Component With React

Document Transition API — Creating a React Hook