코드숨 리액트 6기 6주차 회고

Woohyun Jang
4 min readJan 9, 2022

--

6주차 수업 주제는 routing으로, react-router-dom을 사용하여 Client-Side-Rendering으로 routing 기능을 구현해보았습니다.

routing path

페이지 별로 만든 Page component를 Route 컴포넌트로 uri path와 연결시켜주면 Link 컴포넌트를 사용하여 페이지간 이동이 가능합니다.

테스트 코드를 작성할 때는 실제 구현에서 사용하는 BrowserRouter 대신 MemoryRouter로 앱을 wrapping하고, 의도한 페이지가 렌더링 되었는지를 테스트해보았습니다.

다만 CSR로 구현된 싱글페이지에 대한 routing이기 때문에 기본적으로는 원하는 uri를 브라우저에 검색해서 진입할 경우에는 Not Found가 발생합니다. 따라서 존재하지 않는 페이지로 접근하면 index.html로 redirect하도록 webpack에 추가적인 설정을 해주었습니다.

// webpck.config.jsmoduel.exports = {
// ...
devServer: {
historyApiFallback: {
index: 'index.html',
},
},
// ...
}

이 과정에서 한 가지 문제점을 만났는데 unit test에서는 정상적으로 동작하던 restaurant의 상세페이지가 실제 브라우저로 접근할 경우 /restaurants/main.js 파일을 찾을 수 없다는 에러와 함께 페이지가 정상동작하지 않았습니다.

다행히 함께 수업을 듣는 GUAJEGUICHAN 님이 index.html에 있는 main.js 스크립트 태그를 제거하면 해결된다는 힌트들 주셨고, 해당 파일의 경로가 url경로와 무관하게 항상 프로젝트 root에 존재하는 main.js파일을 읽어오도록 수정해서 해결했습니다🙂

Page 컴포넌트

이전까지 단일 페이지에서 동작하는 앱을 FLUX 패턴으로 구현하다가 이번 수업부터 새로 routing과 여러 page들이 생겨나면서 Page 컴포넌트를 새로 만들게 되었고, 기존에 존재하는 Container 컴포넌트와 역할을 어떻게 분배해야 할지에 대한 고민이 있었습니다. 처음 시도할때는 컴포넌트가 너무 잘게 쪼개지면 depth가 너무 깊어질것 같아서 Container 컴포넌트의 역할을 Page 컴포넌트에서 함께 해주도록 구현했지만 결국에는 둘의 역할을 명확히 분리하는것이 테스트 코드 작성에도 용이하고, 재사용성 측면에서도 유리하겠다는 결론에 도달했습니다.

제가 나눈 역할은 다음과 같습니다.

Page

  1. 유저의 권한 체크: 요청을 보낸 클라이언트가 해당 페이지에 접근할 권한이 있는지 확인하여 권한이 없다면 로그인 페이지로 redirect 또는 Container에 권한 없는 유저라는 데이터 전달
  2. uri query parameter에서 필요한 데이터 추출
  3. Container에 전달할 데이터를 service에서 조회
  4. Container에서 필요한 데이터를 props로 전달

Container

  1. props로 전달 받은 데이터를 기반으로 state(또는 store) 초기화 및 update
  2. event handler 생성
  3. Presenter에서 필요한 데이터를 props로 전달

Presenter

  1. props로 전달 받은 데이터를 기반으로 화면 렌더링

가장 고민이 되었던 부분은

  • Page의 3번: service를 통해서 화면에 필요한 데이터를 가져오는 역할
  • Container 1번: state 초기화 및 update

의 역할을 Page와 Container 중 어디에서 해주는것이 좋을지 였습니다.

현재 구현하는 앱이 CSR이 아닌 Server-Side-Rendering이라면 어떻게 될까? 라는 고민을 해보면서 나름대로의 기준을 세워나갔습니다.

SSR로 앱을 구현한다면 서버에서 해당 페이지를 생성할 때 필요한 데이터를 불러오는 코드를 가장 최상단, 여기에서는 Page Component(next.js를 예로 들자면 getServerSideProps)에서 수행하게 됩니다. 따라서 api 통신 등 service에서 화면 렌더링에 필요한 최초의 데이터는 Page layer에서 불러오는것이 맞겠다는 생각이 들었습니다.

두번째로 고민했던 state를 관리하는 역할 역시 SSR환경일 때를 상상해보았는데 단일 서버에서 여러 클라이언트들의 상태를 각각 관리하기 위해 Container에서 라우팅 정보와는 독립적으로 Presernter의 상태와 이벤트 핸들링을 관리하는것이 적합하다고 생각했습니다.

아직 복잡도가 높은 앱에서 실제 시도해본 것은 아니라 시행착오가 있을 수 있겠지만, 컴포넌트들의 역할을 잘게 쪼개고 좋은 구조에 대해 고민해볼 수 있었던 유익한 한 주 였습니다:)

--

--