탭 메뉴 구현하기

이은지·2022년 2월 14일
0

사람들이 자기가 구현한 것들(이론 말고) 왜 기록하는지 몰랐었는데, 이제 알겠다.
구현을 해야되니 하긴 했는데 이게 베스트 방법인지 모르겠어서 혹시 나중의 내가 봤을 때 더 나은 방법이 존재할까 싶은 생각에 기록해둔다. 퇴사 전에 짬내서 기록.

🥐 구현 목표

가장 기본적인 구현 목표는 다음과 같았다.

  • 화면구성: 한 페이지 내에 탭 메뉴가 존재해서, 어떤 탭을 클릭하냐에 따라 다른 컨텐츠를 보여주어야 함. 편의상 1번 탭과 2번 탭이라고 칭하겠다.
  • API: 두 가지 탭에 필요한 정보를 하나의 response에 담아서 줌
  • 동적 페이지로, 사용자의 액션이 발생하면 서버에 정보를 재요청 해야 함

추가적인(좀 더 구체적인) 구현 목표에는 다음과 같은 것들이 있었다.

  • 각 탭을 오고갈 수 있는 화면 하단의 플로팅 버튼
  • 2번 탭에서 특정 사용자 액션이 발생하면 1번 탭의 컨텐츠가 업데이트 되어야 함 ➡️ 탭 메뉴 전환 시 서버 요청이 발생해야
  • 2번 탭에서 특정 사용자 액션이 발생 ➡️ 모달창을 띄움 ➡️ 모달창 내 버튼을 클릭하면 1번 탭으로 이동, 사용자가 1번 탭으로 이동하기 전에 사용자 액션으로 인한 컨텐츠 업데이트가 완료되어야 함

🥞 구현 방식과 이유

우선 컴포넌트 구성은 다음과 같았다.

  • OwnerHome.js
    -세미 컨테이너 컴포넌트. 서버에 정보를 요청한다.
    -조건(사용자가 현재 선택한 tab)에 따라 두 개의 하위 컴포넌트 중 하나를 렌더링한다.
    -탭 메뉴를 포함하고 있다.
    -두 탭에 공통적으로 포함되는 navbar, footer를 포함한다.

  • CharacterHome.js, NeoHome.js
    -각 탭에 해당하는 컴포넌트.
    -세미 컨테이셔널 컴포넌트. 사용자의 액션이 발생했을 시 서버에 정보를 요청한다.

"세미"라는 표현을 붙인 건 딱 그렇다고 이야기하기엔 애매한 부분들이 존재해서이다.
이 부분이 애초에 문제였을지도?

OwnerHome.js 가 상위 컴포넌트인 것은 맞지만, NeoHome.js 에서 CharacterHome.js에 영향을 미치기 위해 상위 컴포넌트를 경유하는 건 뭔가 부자연스럽게 느껴졌다. (애초에 OwnerHome.js도 일종의 프레젠테이셔널 컴포넌트였기도 하다. 컴포넌트의 depth가 깊은 게 문제였을 수도)
NeoHome.js 내의 모달에 있는 버튼을 클릭하면 탭 이동이 됐어야 했기 때문에, 탭 이동을 관리할 수 있는 중앙 관리자 같은 게 필요했음.

부모 컴포넌트에서 자식 컴포넌트로 데이터를 보내는 건 props를 이용하면 되지만, 그 반대의 경우는 복잡하고 부자연스럽다. 이럴 때 사용하는 게 Redux라 배웠다...!

그래서 탭 이동 및 스크롤을 관리하는 리듀서를 만들었다. neohome_reducer.js

const initialState = {
  tab: "character",
  nickname: "",
  scroll: false,
  scroll_to: "",
};

해당 리듀서를 일종의 리모컨 처럼 사용했다.

탭 메뉴 변경이 필요할 때 SET_TAB이라는 액션을 디스패치 했다.
dispatch({type: "set_tab", payload: "neo"})

그러면 store의 정보가 바뀌면서 OwnerHome.js 의 리렌더링이 일어나고? 해당 탭 컴포넌트가 렌더링됨.

근데 사실 적다보니까 이게 문제가 아니고 컴포넌트 리렌더링이 언제 일어나는지 같은 리액트 기본 지식이 부족한 게 문제라는 생각이 듦. 그래서 요기서 스탑하고, 이론 공부 보충되면 다시 적을랭
얼른 이론 공부 하고 싶다는 생각을 한다,,, 급 마무리

0개의 댓글