
개발을 시작하기 전에, 페이지와 요소를 기능 및 UI로 최대한 잘게 나누어 협업에 문제가 없도록 하기 위해 라우터를 나누는 작업을 진행했다.
사전에 라우터를 정리하면서 앞으로 개발하게 될 페이지를 대략적으로 나누고,
그 다음 각 페이지 내에 사용할 컴포넌트들을 나누어 보면서 공통으로 들어갈 컴포넌트를 미리 정해두는 등의 작업을 통해 더 효과적으로 협업을 진행할 수 있었다.
라우터 구조는 이전에 작성한 유저 플로우를 기반으로 총 3개로 나누었다.

PublicRoute는 로그인을 하지 않은 유저가 이용하는 라우터로, 백오피스 성격을 지닌 Calit 프로젝트는 로그인 한 유저만 들어올 수 있도록 구현해야 했다.
따라서 recoil을 이용해 로그인 상태를 구독하여 로그아웃을 하기 전에는 PublicRoute로 이동할 수 없게 작업을 진행했다.
PrivateRoute는 로그인을 한 유저가 이용하는 라우터로, 로그인을 하지 않은 유저가 PrivateRoute로 입장시 강제로 PublicRoute로 이동하도록 되어있다.
또한 실시간으로 로그인 한 유저의 정보를 확인하고 있어 프로젝트 수정, 삭제 혹은 소속된 프로젝트에서 내보내질 시 자동으로 프로젝트 리스트 내역이 변경되도록 설계했다.
ProjectCheckRoute는 협업의 가장 큰 단위인 프로젝트 내에 해당 유저가 소속되어 있는지 확인하는 라우터로, 만약 소속되어 있지 않다면 자동으로 PrivateRoute로 이동하도록 되어있다.
이번 Calit 프로젝트에서 제일 중요한 것은 실제 협업이 이루어지는 프로젝트 메인 페이지(Project.tsx)라고 할 수 있다.
개발 진행하기 전 기능을 정할때, 초대 링크를 보낸다면 해당 URL을 통해 바로 프로젝트로 들어올 수 있도록 하기 위해 해당 기능을 구현하기 위한 방법을 모색하고 있었다.
단순히 프로젝트 링크를 보내는 것이 아닌, URL을 통해 사이트 입장시 경우에 따라 프로젝트 페이지의 모달 또한 띄울 수 있어야 했다.
가장 직관적이면서 가장 쉬운 UI를 구현하기 위해 페이지 이동이 아닌 모달을 사용하기로 결정하였다.

첫번째로는 프로젝트 내부 아이템들까지의 링크를 path로 만들어 진행하고자 했지만,
메인 페이지에 여러 모달이 뜨는 형태로 구현해야 했기에 path를 사용하기에는 큰 어려움이 있었다.
history 패키지의 createBrowserHistory를 이용하면 화면 렌더링 없이 URL을 변경할 수 있었지만,
이후 해당 URL을 다시 주소창에 입력해 이동한다면 BrowserRouter에서 해당 주소를 찾지 못하는 문제가 발생했다.

또한 history 패키지를 사용하는 코어 라이브러리인 react-router, 이를 이용한 react-router-dom의 BrowserRouter를 사용하고 있었기 때문에 한번에 2개의 history 객체를 이용하고자 하는건 지나치게 복잡한 구조로 진행하고 있는 듯 하였다.
따라서 path가 아닌, query를 이용해보고자 했다.
react-router-dom 에서 제공하는 useSearchParams 훅을 이용하면 현재 사이트의 queryString을 확인할 수 있었고,
query에 변화가 생길때 마다 리렌더링을 촉발하여 모달등을 문제 없이 화면에 쉽게 띄울 수 있었다.
최초 해당 링크로 입장시에 훅을 이용해 렌더링 전에 query 정보를 확인할 수 있었고,
query의 변화를 훅으로 관리하기 때문에 첫번째 방법보다는 좀 더 리액트스러운 방법으로 구현할 수 있게 되었다.

아래는 간단한 구현 코드이다
function Project() {
const [searchParams, setSearchParams] = useSearchParams();
let isCanbanShow;
let isTodoShow;
const handleCalClick = () => {
setSearchParams();
};
const handleCanbanCLick = () => {
setSearchParams({ canbanID: "1234" });
};
const handleTodoCLick = () => {
setSearchParams({
canbanID: searchParams.get("canbanID")!,
todoID: "5678",
});
};
if (searchParams.has("canbanID")) isCanbanShow = true;
if (searchParams.has("todoID")) isTodoShow = true;
return (
<>
<div>Project</div>
<Btn type="button" onClick={() => handleCalClick()}>
calender
</Btn>
<Btn type="button" onClick={() => handleCanbanCLick()}>
canban
</Btn>
<Btn type="button" onClick={() => handleTodoCLick()}>
todo
</Btn>
{isCanbanShow ? <div>Canban</div> : null}
{isTodoShow ? <div>Todo</div> : null}
</>
);
}
개발하기 전 유저 플로우를 바탕으로 라우터 및 컴포넌트를 사전에 분할하여 더욱 원활한 협업을 진행할 수 있었다.
컴포넌트 분할 과정은 블로그로 작성하지 않았지만, 이 과정을 통해 사전 작업 분배를 손쉽게 진행하고
지금 놓치고 있는것들을 다시 한번 확인할 수 있었다.
또한 이번 기회에 아무 생각없이 사용하던 react-router-dom에 대해 좀 더 공부할 수 있었고,
history API, history 패키지, react-router의 구현 등 좀 더 상세한 내용을 알 수 있었다.