React.js react router dom (V5 => V6)

강정우·2023년 1월 31일
0

react.js

목록 보기
38/45
post-thumbnail
post-custom-banner

변경

Switch => Routes

<Switch>
  <Route path={"/"} exact><Redirect to={"quotes"}/></Route>
  <Route path={"/quotes"} exact><AllQuotes/></Route>
  <Route path={"/quotes/:quoteId"}><QuoteDetail/></Route>
  <Route path={"/new-quote"}><NewQuotes/></Route>
  <Route path={"*"}><NotFound/></Route>
</Switch>
<Routes>
	<Route path={"/"} element={<Redirect to={"quotes"}/>}/>
	<Route path={"/quotes"} element={<AllQuotes/>}/>
	<Route path={"/quotes/:quoteId"} element={<QuoteDetail/>}/>
	<Route path={"/new-quote"} element={<NewQuotes/>}/>
	<Route path={"*"} element={<NotFound/>}/>
</Routes>
  • Route를 감싸는 태그 변환
  • exact prop의 삭제 => exact가 default로 실행되어 이제 항상 정확한 path만들 찾아감.
  • 이때 만약 경로의 초반부분만 startwith하고 나머지는 아무거나 와도 상관없다면
<Route path={"/quotes/*"} element={<QuoteDetail/>}/>

이렇게 작성하면 된다.

  • 또한 V6에서는 최적의 라우트를 찾는 알고리즘 성능이 개선되었기에 순서상관없이 최적의 라우트 컴포넌트를 제공한다.

Redirect => Navigate

<Route path={"/"} element={<Redirect to={"quotes"}/>}/>
<Route path={"/"} element={<Navigate replace to={"quotes"}/>}/>
  • 이렇게 Navigate를 추가하면 to prop 컴포넌트의 내비게이션을 내비게이션 stack에 push하게 된다.
    따라서 현재 페이지를 새 페이지로 교체하는 Redirection을 원한다면 replace prop도 Navigate에 추가해야 한다.

useHistory => useNavigate

history.push({
	pathname:location.pathname,
	search: `?sort=${(isSoringAscend ? "desc" : "asc")}`,
});
const navigate = useNavigate();

navigate({
	pathname:location.pathname,
	search: `?sort=${(isSoringAscend ? "desc" : "asc")}`,
},{replace:true});
  • useEffect 훅에서 이동하거나 HTTP 요청이나 다른 작업을 완료했을 때 이런식으로 이동한다.
  • 또한 리디렉션하려면 두 번째 인수를 객체로 전달하고 객체의 몇 가지 옵션 중 replace를 true로 설정한다.
    그러면 현재 라우트가 새 라우트로 교체하는데 새 라우트를 내비게이션 스택으로 푸시하는 대신 리디렉션하는 개념이다.
navigate(-2);
  • 숫자를 전달할 수도 있다.
    -1을 전달하면 이전 페이지로 이동하고
    -2를 전달하면 이전 페이지의 전 페이지로 이동하고
    1을 전달하면 다음 페이지로 이동하는 식이다.
    앞으로 가기, 뒤로 가기 내비게이션도 이 navigate 함수에서 가능하다.

Nested Route (중첩라우트)

<Route path={`${match.path}`} exact>
  <div className={"centered"}>
    <Link className="btn--flat" to={`${match.url}/comments`}>Load Comments</Link>
  </div>
</Route>
  • 반드시 싱글 Route라고 해도 Routes 태그로 한 번 감싸주어야 한다.
<Routes>
  <Route path={`${match.path}`} element={
      <div className={"centered"}>
        <Link className="btn--flat" to={"comments"}>Load Comments</Link>
      </div>
    }/>
  <Route path={"comments"} element={<Comments/>}></Route>
</Routes>
  • 중첩된 라우트에 필요한 로직과 구문도 변경되었다.
    중첩된 라우트를 사용할 때는 부모 라우트부터 시작해야 한다.
  • 이는 Route 태그 뿐만 아니라 Link 태그도 동일하다.
<Routes>
  <Route path={"/quotes"} element={<AllQuotes/>}/>
  <Route path={"/quotes/:quoteId"} element={<QuoteDetail/>}/>
  <Route path={"/quotes/*"} element={<QuoteDetail/>}/>
  <Route path={"*"} element={<NotFound/>}/>
</Routes>
  • 이런식으로 반드시 *가 있어야 한다. 왜? 앞서 언급했듯 앞으로 모든 Route 태그는 exact가 default로 적용되기 때문이다.
  • 또한 모든 nested Route는 상대경로로 지정된다.
    즉, 부모로부터 tree형식으로 묶여있어 더이상 full path를 적지 않아도 된다. 자식 경로만 적으면 된다.

V6 Route 모으기

<Routes>
  <Route path={"/"} element={<Navigate replace to={"quotes"}/>}/>
  <Route path={"/quotes"} element={<AllQuotes/>}/>
  <Route path={"/quotes/:quoteId"} element={<QuoteDetail/>}/>
  <Route path={"/quotes/*"} element={<QuoteDetail/>}>
    <Route path={"comments"} element={<Comments/>}/>
  </Route>
  <Route path={"/new-quote"} element={<NewQuotes/>}/>
  <Route path={"*"} element={<NotFound/>}/>
</Routes>
  • 만약 당신이 RRD V6를 사용한다면 이제 nested route는 한 곳에 모아 이렇게 이쁘게 관리하자
  • 근데 또 웃긴게 이렇게 관리는 편하지만 해당 코멘트 컴포넌트가 어느곳에서 렌더링 되야하는지 어떻게 알까? 그것 또 가서 잡아줘야한다.

생성

<Outlet>

return (<Fragment>
          <HighlightedQuote text={loadedQuote.text} author={loadedQuote.author}/>
          <div className={"centered"}>
              <Link className="btn--flat" to={"comments"}>Load Comments</Link>
          </div>
          <Outlet/>
    	</Fragment>);
  • nested router가 삽입될 위치를 React Router에 알리기 위해 react-router-dom에서 가져올 수 있는 새 컴포넌트가 바로 Outlet 컴포넌트이다.
  • self closing tag를 사용해 추가하면 되고, 일종의 플레이스홀더로 중첩된 라우트 콘텐츠를 삽입할 위치를 React Router에게 알려준다.

삭제

Route의 exact prop

  • exact prop의 삭제 => RRD V6에선 exact가 default로 실행되어 이제 항상 정확한 path만들 찾아감.
<li><NavLink to={"/quotes"} activeClassName={classes.active}>All quotes</NavLink></li>
<li><NavLink to={"/new-quote"} activeClassName={classes.active}>Add a quotes</NavLink></li>
  • className은 단순히 클래스 이름만 취하지 않고 함수를 인수로 갖는다.
    이 함수에서는 해당 링크와 내비게이션의 현재 상태에 관한 정보를 얻을 수 있다.
    navData를 얻는 것인데, navData 인수는 함수가 실행될 때 React Router가 이 함수에 제공하며 이 함수는 React Router에 의해 NavLink를 평가하거나 내비게이션이 변경될 때마다 실행된다.

  • React Router로부터 얻는 navData 객체 안에서 isActive props에 접근하여 현재 선택된 경로에 대한 링크가 활성화되었다면 이는 true고 이렇게 하면 NavLink에 적용해야 할 className을 동적으로 반환할 수 있다.

<li><NavLink to={"/quotes"} ClassName={(navData)=> navData.isActive?classes.active:""}>All quotes</NavLink></li>
<li><NavLink to={"/new-quote"} ClassName={(navData)=> navData.isActive?classes.active:""}>Add a quotes</NavLink></li>

<Prompt>

  • 프롬프트 태그는 form에서 사용자가 뒤로가기나 나가기를 잘 못 눌렀을 때 그것을 방지해주고자 나온 태그인데 이게 삭제되어버려서 당분간은 수동적으로 이를 구현해야한다. 그래서 몇몇 회사는 불편함을 감수하고서라도 굉장히 중요한 기능이기에 route V5을 유지하는 곳도 있다.

<useRouteMatch>

  • 변경점 nested Route에서 본 것 처럼 상대경로로 위치를 잡기 때문에 그냥 안 쓰임
profile
智(지)! 德(덕)! 體(체)!
post-custom-banner

0개의 댓글