중첩라우팅(Sub Route)

둘둘·2021년 1월 12일
1

야매 중첩라우팅

내가 원한건 MyPage의 Tab 중 하나인 saved를 클릭했을때 url이 test1/saved 이런식으로 표현되길 바랬다!
그리하여 첫 시도...!

Routes.js

앞뒤로는 생략하고 중요한 부분만!!

// 생략
  <Switch>
        <Route exact path="/:username/upload" component={MyPage} />
        <Route exact path="/:username/saved" component={MyPage} />
        <Route exact path="/:username" component={MyPage} />
  </Switch>

//생략

MyPage.js

마찬가지로 앞뒤로는 생략하고 Tabs 컴포넌트만!!
MyPage의 디폴트 tab인 PostList에는 props를 넘기지 않고, saved와 upload에만 props를 넘겨주고 있다


// 생략
<Tabs
  tabs={[
    {
      title: "업로드",
      render: () => <UploadTemplate upload="upload" />
    },
    {
      title: "게시물",
      render: () => <PostList postList={userFeed} />
    },
    {
      title: "저장됨",
      render: () => (
        <PostList active="2" postList={saves} saved="saved" />
      )
    }
  ]}
  active={0}
  defaultActive={1}
/>
// 생략

Upload.js

const UploadTemplate = ({ upload }) => {

  useEffect(() => {
    if (upload) history.push(`/${username}/upload`);
    if (upload === undefined) history.push(`/${username}`);
  }, [upload]);

// 생략
}

props에 upload가 있을 경우 주소값을 바꾸게했는데 다시 보니 너무 눈가리고 아웅인거 같다!
그래서 중첩라우팅을 적용해보기로 했다.

중첩라우팅(SubRoute)

기존에는 Routes.js 파일에 온갖 라우팅 기능을 몰아넣었는데
중첩라우팅을 적용할 경우 MyPage에도 react-router-domRoute를 불러와준다!

Routes.js

야매 버전 중첩라우팅을 시도했을 때 썼던 Route는 살짝 지워주고
아래의 MyPage 컴포넌트를 불러오는 경로만 살려둔다! 살려는 드릴게 ㅎ

잊지 말아야할 한 가지!!
살려둔 경로에서 exact를 꼭 지워준다
exact를 살려두면 nesting을 할 수 없기 때무네...!

  <Switch>
      //  <Route exact path="/:username/upload" component={MyPage} />
      // <Route exact path="/:username/saved" component={MyPage} />
        <Route path="/:username" component={MyPage} />
  </Switch>

완성된 Tab 이미지 (갑자기?)

  • 게시물을 클릭했을 경우 url은 http://localhost:3000/test1
  • 업로드를 클릭했을 경우 url은 http://localhost:3000/test1/upload
  • 저장됨을 클릭했을 경우 url은 http://localhost:3000/test1/saved

  • 아래의 코드에서 보면 Link 대신에 NavLink를 썼는데 이걸 쓰면 active효과를 좀 더 쉽게 줄 수 있다.
  • 기본적으로로 activeClassNameisActive라는 속성이 있어서 입맛에 맞게 활용 가능쓰!
  • activeStyle도 적용할 수 있는데 세번 쓰기 싫어서 scss파일에 정의했다ㅋㅋ
  • isActive에 설정값을 따로 주지 않았을 때 active 상태가 동시에 2개 잡혀서 저렇게 로직을 짰는데.. 나중에 좀 더 단순화 시켜봐야지 ㅠㅠ

MyPage.js

import React, { useState, useEffect } from "react";
import { Link, Route, useLocation, NavLink } from "react-router-dom";

const MyPage = ()=> {
  const location = useLocation();
  const linkedName = location.pathname.slice(1);
// MyPage UI 생략하고 Tab 부분만 씀!
<nav className="mypage__tabs">
   <ul>
     <li>
       <NavLink
         to={`/${foundUser?.username}/upload`}
         className="mypage__nav__link"
         activeClassName="activeRoute"
         isActive={() =>
           location?.pathname === `/${foundUser?.username}/upload`
         }
        >업로드</NavLink>
     </li>
     <li>
        <NavLink
          to={`/${foundUser?.username}`}
          className="mypage__nav__link"
          activeClassName="activeRoute"
          isActive={() =>
            location?.pathname === `/${foundUser?.username}`
          }
          >게시물</NavLink>
     </li>
     <li>
       <NavLink
         to={`/${foundUser?.username}/saved`}
         className="mypage__nav__link"
         activeClassName="activeRoute"
         isActive={() =>
           location?.pathname === `/${foundUser?.username}/saved`
         }
         >저장됨</NavLink>
     </li>
  </ul>
</nav>
                                       
// 여기에 Route를 정의
<Route path="/:username/upload" component={UploadTemplate} />
  <Route
    path="/:username"
    render={() => (
      <PostList
        postList={
        userInfo?.username === linkedName ? userFeed : linkedFeed
        }
      />
    )}/>
  <Route
    path="/:username/saved"
    render={() => <PostList postList={saves} />}/>                           
}

다음 시간엔 이거보다 더 신기했던 react-router-dom을 이용해 상세페이지와 modal창의 url이 같도록 넘겨주는 것을 포스팅하기로..!
적용은 했는데 시간 아끼려고 포스팅 못한 것들이 넘나 많다 😂

Reference

profile
Dooreplay! 안 되면 될 때까지,

1개의 댓글

comment-user-thumbnail
2021년 10월 19일

중첩 라우팅을 위해서는 exact를 지웠어야 했군요... 꿀팁감사합니다.

답글 달기