본문 바로가기

Study/npm Libraries

React-router(v6)

$ npm i react-router-dom@6
$ npm i react-router-dom@latest

 

+) upgrainig from v5 

BrowserRouter

  • index.js에 똑같이 제공해 주어야 한다. 

Switch => Routes

import { Redirect, Route, Routes } from 'react-router-dom';

function App() {
  // ... 
  
  return (
      <Routes> 
         <Route path='/'>
            <Redirect to='/quotes' />
         </Route>
         <Route path='/quotes' element={<AllQuotes />} />
         <Route path='/new-quotes' element={<NewQuote />} />
         <Route path='/quotes/:quoteId' element={<QuoteDetails />} />
         <Route path='*' element={<NotFound />} />
      </Routes>
  );
}

 

  1. element | Route의 자식 요소로 렌더링할 컴포넌트를 전달하는 것이 아니라, element props으로 전달한다. 
  2. without exact | v6는 exact props을 전달하지 않아도, 정확히 일치하는 route를 선택해서 반환한다. 
  3. "something/*" | v5에서 exact props을 전달하지 않았을 때와 똑같이 작동한다.
    • something으로 시작하는 모든 route에 주어진 element를 렌더링한다.
    • 단 something/:id와 같은 특정 segment가 포함된 Route가 정의되어 있는 경우, 그 특정 경로만 렌더링한다. 
    • => 즉, 모든 경로 중 가장 최적의 경로를 찾아서 렌더링한다.
    • => Route를 작성하는 순서를 주의할 필요가 없다. 

nestedRoute

컴포넌트에서 중첩 route 사용할 때

const Component = () => {
  return (
    <section>
      <h1>Welcome Component</h1>
      <Routes>
      // 상위 경로를 포함하지 않는다("/component/nested" ❌)
        <Route path="nested" element={<p>nested!</p>} />
      </Routes>
    </section>
  )
}

// app.js
// ... 

return (
  <Routes>
    // "/component/*" 로 변경해 주어야 한다  
    <Route path="/component" element={<Component />} />
  </Routes>
)

 

  1. 컴포넌트 안에서 중첩 경로를 작성할 때에도 Routes 컴포넌트로 묶어주어야 한다.
  2. "/component" url에 접속했을 때 Component가 렌더링 되어야 한다. 
  3. "/component/nested" url에 접속했을 때 Component와 함께 "nested!" 문구가 렌더링 되어야 한다. 
    • app.js에서 path=/component/*로 변경해 주어야 한다. 
    • 그렇지 않으면 리액트 라우터는 "/component/nested" url이 "/component" url과 일치한다고 판단한다(v6에서는 기본적으로 v5의 switch와 exact를 적용했을 때와 같이 일치하는 path 하나 만을 찾기 때문에). 
    • 중첩 경로의 path에는 상위 경로의 path를 포함하지 않는다.
      • Route 컴포넌트 뿐만 아니라, Route에 의해 렌더링 되는 Link의 path 속성에도 해당한다.  

app에서 중첩 route 사용할 때

// app.js

return (
  <Routes>
    <Route path="/component" element={<Component />}>
      <Route path="nested" element={<p>nested!</p>}/> 
    </Route>
  </Routes>
)

// Component.jsx
import { Outlet } from 'react-router-dom'; 

const Component = () => {
  return (
    <section>
      // <Outlet /> 여기에 작성하면 nested! 문단이 h1 위에서 렌더링 된다 
      <h1>Welcome Component</h1>
      <Outlet /> 
    </section>
  )
}

 

  1. Route 컴포넌트 안에 Route를 위치시킴으로써 중첩 경로를 작성할 수 있다(이 때에는 와일드 문자(*)가 필요하지 않다). 
  2. "/component/nested" url에 접속했을 때 <Component />와 <p>nested!</p>가 함께 렌더링 되려면, Outlet이라는 컴포넌트를 가져와야 한다. 
    • Outlet | 자식 route가 렌더링할 컴포넌트가(예제에서는 <p></p>) 정확히 어디에 위치할지를 부모 route에 전달해 준다. 

Link, NavLink

const MainNavigation = (props) => {
  return (
    <header className={styles.header}>
      <NavLink to='/quotes' className={styles.logo}>
        Great Quotes
      </NavLink>
      <nav className={styles.nav}>
        <ul>
          <li>
            <NavLink to='/quotes' className={(data)=>data.isActive? styles.active : ''}>
              All quotes
            </NavLink>
          </li>
          <li>
            <NavLink to='/new-quotes' activeClassName={styles.active}>
              Add a Quote
            </NavLink>
          </li>
        </ul>
      </nav>
    </header>
  );

 

  • NavLink 
    1. activeClassName 속성이 사라졌다.
    2. 대신 className을 사용하고, 그 값으로 함수를 전달한다. 
    3. 리액트 라우터는 함수의 인자로, NavLink에 대한 데이터를 전달해 준다. 

Redirect => Navigate

function App() {
  // ... 
  
  return (
      <Routes> 
         <Route path='/' element={<Navigate to='/quotes' />} />
         <Route path='/quotes' element={<AllQuotes />} />
         <Route path='/new-quotes' element={<NewQuote />} />
         <Route path='/quotes/:quoteId' element={<QuoteDetails />} />
         <Route path='*' element={<NotFound />} />
      </Routes>
  );
}

 

  1. v6에서는 더이상 Redirect 컴포넌트를 제공하지 않는다. 
  2. Navigate은 내부적으로, history push를 이용해서 사용자를 to prop에 전달된 페이지로 이동하게 한다. 
  3. replace prop을 전달하면, push 대신 replace를 사용한다. 

useHistory => useNavigate

import { useNavigate } from 'react-router-dom';

const QuoteContextProvider = (props) => {
  const navigate = useNavigate(); 
  // ...
  sendRequest(config, transformData);
  navigate('/quotes', {replace:true});
}

 

  1. v5에서 useHistory 훅을 호출하면 객체를 반환한다. 사용자의 action에 따라 url을 redirect 할 수 있도록 push, replace와 같은 메서드를 제공한다. 
  2. v6는 useHistory 대신 useNavigate 훅을 제공하는데, 객체가 아니라 함수를 반환한다. 
  3. navigate에 path를 전달하는 대신 숫자를 전달할 수도 있는데, -1을 전달하면 이전 페이지로 push 한다. 
  4. +) useNavigate과 useLocation을 이용하면, 서로 다른 컴포넌트끼리 state를 주고받을 수 있다.

Prompt 

  1. v5에서 사용자가 실수로 페이지를 벗어나지 않게 만들 때 사용할 수 있는 컴포넌트이다. 
  2. v6에서는 지원하지 않음

'Study > npm Libraries' 카테고리의 다른 글

React with web accessibility  (0) 2022.09.19
TanStack Query(React Query)  (0) 2022.07.24
React-router  (0) 2022.07.01
React-redux & Redux-toolkit  (0) 2022.06.30
what is Redux?  (0) 2022.06.29