위코드 에서 공부하며 정리한 내용입니다.
리액트 컴포넌트는 UI 표현이나 동작 로직 등 여러 역할로 사용됩니다. 컴포넌트는 재사용할 수 있는 최소단위 UI 지만, 이런 기능들이 복잡하게 들어갈 수록재사용이 어렵고 가독성과 유지보수성이 떨어집니다. 이를 막고자 컴포넌트를 관심사에 따라 분리(비슷한 기능을 하는 코드끼리 별도 관리)해서 사용하면 좋습니다.
view 와 로직을 분리하거나 state 에 따라 분리할 수 있습니다. 이 외에 다양한 기준들이 있습니다. 아래 예시는 UI 에 집중해서 컴포넌트를 분리한 예시입니다.
컴포넌트를 분리하려면 두가지 UI 에서 동일한 요소와 다른 요소를 파악한 후 다른 요소만 데이터로 구성해 동일한 컴포넌트에 props로 데이터를 넘겨주면 됩니다. 아래처럼 두 개의 내용을 표현하는 두 개의 컴포넌트가 있을 때
const isSelectLogin = true;
return (
<>
<p>왁챠피디아 예제</p>
{isSelectLogin ? <Login /> : <Signup />}
</>
);
로그인과 회원가입 화면의 디자인이 같고, 다른 것이 제목, 연결 링크, 텍스트 정도라면 아래처럼 각각의 데이터를 만들고
const LOGIN_DATA = {
title: "로그인",
linkText: "계정이 없으신가요? 회원가입"
url: "/signup",
}
const SIGNUP_DATA = {
title: "회원가입",
linkText: "이미 가입하셨나요? 로그인"
url: "/login",
}
하나의 컴포넌트에서 props 로 데이터를 넘겨주는 데 그 데이터는 조건에 따라 위에 생성한 두 데이터 중 하나를 반환합니다.
return (
<div className="modal">
<Signup content={isSelectLogin ? LOGIN_DATA : SIGNUP_DATA} />
</div>
);
이렇게 전달한 props 는 구조분해할당으로 받으면 사용하기 좋습니다.
const Signup = ({ content }) => {
const { title, linkText, url } = content;
return ( );
}
이렇게 전달한 데이터를 필요한 곳에 넣어주면,
const User = ({ content }) => { // 로그인과 회원가입 두가지 역할을 하므로 User 로 변경
const { title, linkText, url } = content;
return (
<div className="watchaContainer">
<header className="logo" />
<h2 className="title">{ title }</h2> // 데이터 사용
<form>
<input className="input" type="text" placeholder="이름" />
<input className="input" type="email" placeholder="이메일" />
<input className="input" type="password" placeholder="비밀번호" />
<button className="button">{ title } </button> // 데이터 사용
<Link to={ url } className="link"> // 데이터 사용
{ linkText } // 데이터 사용
</Link>
</form>
</div>
);
}
로그인의 경우 이름을 입력하는 input 이 없다면, 회원가입일 때만 해당 input 태그가 나오도록 && 연산자를 사용해서 아래처럼 써줄 수 있습니다.
{ title === "회원가입" && (
<input className="input" type="text" placeholder="이름" />
)}
위에서 사용한 isSelectLogin 은 현재 위치한 url 이 무엇인지 확인합니다. 코드는 아래와 같습니다.
const location = useLocation(); // 현재 위치한 url 값 가져오는 메소드 useLocation()
const currentURL = location.pathname // 현재 위치한 url 값을 변수에 담고
cosnt isSelectLogin = currentURL === "/login" && true; // 현재 url 이 /login 이면 true, 아니면 false