원티드 프리온보딩으로 react-router를 가볍게 구현하고 난 후, 실제 react router는 어떻게 구현되어 있을지, 깃헙에 들어가서 살펴보자.
export function Route(_props: RouteProps): React.ReactElement | null {
invariant(
false,
`A <Route> is only ever to be used as the child of <Routes> element, ` +
`never rendered directly. Please wrap your <Route> in a <Routes>.`
);
}
Route는 별 내용이 없다.
사실 Route가 하는 일이 없기 때문이다. Route는 렌더링을 담당하지 않는다. Route를 렌더링 하는 일은 Routes가 담당하고 있기 때문에, 개발자가 Route를 렌더링하려고 한다면, 에러 메세지를 내뱉을 것이다.
Route는 Routes 내부에서만 사용 가능하다는 것이다.
왜 Route는 아무것도 반환하지 않고 에러 메세지만 가지고 있을까?
나는 Route를 구현할 때, props로 들어오는 컴포넌트를 반환하여 사용하였다. 그러나 react-router에서는 반환하는 값조차 없다.
Route 컴포넌트는 개발자가 직접 렌더링하려고 할 때 에러를 발생시키는 역할만 수행하므로, 실제로는 아무것도 반환하지 않습니다. 이 컴포넌트의 목적은 컴포넌트의 자식으로만 사용되어야 한다는 것을 강제하는 것입니다.
실제로 라우팅과 관련된 로직은 컴포넌트에서 처리됩니다. 컴포넌트는 자신의 자식 요소로서 주어진 모든 요소들을 검사하고, 각각에 대해 해당 경로가 현재 URL과 일치하는지 확인합니다. 일치하는 경우 해당 요소의 children prop으로 주어진 컴포넌트를 렌더링합니다.
따라서 Route 컴포넌트가 직접적으로 무언가를 반환하지 않아도 괜찮습니다. 그 대신, 개발자가 Route를 직접 사용하려고 하면 오류 메시지를 출력하여 이를 방지합니다. 이런 방식으로 React Router는 개발자가 API를 올바르게 사용하도록 유도합니다.
한마디로 렌더링 자체는 Routes에서 담당하고 있어 Route 컴포넌트 자체는 무언가를 하지 않아도 된다는 소리이다.
그렇지만 나는... component를 반환하는데?
Routes로 들어오는 컴포넌트를 console.log에 찍어보았다.
props.components에 react.element가 보인다. 그렇다면, Routes에서 반환하는 값을 현재 렌더링할 컴포넌트로 하면 어떨까?
나는 이제까지 Routes에서 현재 라우팅되는 페이지와 동일한 요소를 반환하기만 했다. 그리고 그걸 Route에서 처리했는데, Route가 아무런 일도 할 필요가 없다면 즉, 그걸 의도한 거라면... Route에서 반환하는 return을 삭제하고 Routes에서 반환한다.
return current.props.components
위의 코드처럼 수정하고 반환해보니 사이트가 잘 작동한다.
아, 물론... home 버튼을 눌렀을 때, 새로고침 없이 가는 건 테스트를 위해 적용하지 않아서 일어나는 일이다.
흥미로운 코드 해체 작업이었다. 리액트는 너무 잘 짜여진 코드라서 내가 제작자의 의도까지 파악할 수는 없지만, 평소 하는 생각과 전혀 다른 방향의 생각이라 재밌었던 거 같다.
물론 혼자서 코드를 파봤다면 머리를 쥐어짰겠지만, AI에게 물어, 물어... 여기까지 온 거 같다. 다음에는 dom-react-router에 대해서도 파보고 싶은데, 아직은... 생각이 없다. 어렵기 때문에...