컴포넌트는 재사용 할 수 있는 최소 UI단위이다. 하지만, 웹의 복잡도와 해당 컴포넌트에서 수행하려는 역할에 따라 복잡해 질 수 있다. 이때, 우리는 관심사의 분리에 대해서 생각해 봐야한다.
💡 관심사의 분리 란?
복잡한 코드를 비슷한 기능을 하는 코드끼리 별도로 관리하는 것
클론코딩 했었던 인스타그램의 로그인, 회원가입 페이지를 분석하여 컴포넌트 재사용을 적용시켜 보도록하자!
위 그림에서 보면 로그인과 회원가입 페이지는 동일한 레이아웃을 갖고 있는 것을 볼 수 있다.
UI의 구성요소 분석이 끝났다면, 어떻게 컴포넌트를 구성해서 재사용 할 수 있을지 파악해야한다.
위와 같은 경우 다른 부분을 다른 코드 혹은 컴포넌트로 처리할 필요 없이 필요한 정보를 데이터로 구성하여 동일한 컴포넌트에 props 로 넘겨줄 수 있다.
const isUser = true;
const LOGIN_DATA = {
title: '로그인'
text = '계정이 없으신가요? 가입하기'
url = '/join',
}
const JOIN_DATA = {
title: '회원가입'
text = '계정이 이미 있으신가요? 로그인하기'
url = '/login',
}
...
return(
<>
<User data={isUser ? LOGIN_DATA : JOIN_DATA}/>
</>
)
다음으로 회원가입 페이지에는 성명 과 사용자 이름 2개의 입력창이 더 필요하다. props로 전달해주는 DATA에 태그 자체를 만들어서 보내주는 방법도 있지만, 조건부 렌더링 으로 필요한 <input />
더 추가해주는 방식으로 만들어보도록 하겠다.
조건부 렌더링을 할때는 이미 DATA로 넘겨준 값 중 title을 사용해서 조건을 만들어 주면된다.
{title === '회원가입' && <input type="text" placeholder="성명" />}
{title === '회원가입' && <input type="text" placeholder="사용자 이름" />}
마지막으로 컴포넌트 재사용을 위해 구성한 데이터를 하나의 컴포넌트에서 가져다 쓰면된다.
const User = ({data}) => {
const {title, text, url} = data; // 전달받은 props 구조분해할당으로 사용
return(
<>
<div className="container">
<h1 className="logo">Instagram</h1>
<p className="title">{title}</p>
<form>
<input
type="text"
name="email"
placeholder="이메일"
/>
{title === '회원가입' && <input type="text" placeholder="성명" />}
{title === '회원가입' && <input type="text" placeholder="사용자 이름" />}
<input
type="password"
name="password"
placeholder="비밀번호"
autoComplete="on"
/>
<button className="login-btn">{title}</button>
</form>
</div>
<Link to={url}>{text}</Link>
</>
)
}
부모 컴포넌트에 있는 isUser
의 값이 true인 경우에는 로그인에 해당하는 UI가 보여질 것이고 false인 경우에는 회원가입에 해당하는 UI가 구성될 것이다!
마무리✨
정리하자면, 컴포넌트의 재사용은 넘겨받는 데이터에 따라 다른 화면을 보여주게 하는 것이라고 생각하면 될 것 같다. 작업을 하다보면 똑같은 UI인데 안에 들어가는 내용이 달라서 여러번 만들어 줬던 경험이 있었는데 컴포넌트의 재사용을 통해 훨씬 더 효율적으로 컴포넌트를 관리할 수 있을 것 같다.