[React] ๐Ÿ“œ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ v6 ์‚ฌ์šฉ๋ฒ•๐Ÿงน

TATAยท2023๋…„ 1์›” 25์ผ
0

React

๋ชฉ๋ก ๋ณด๊ธฐ
3/32

โœ”๏ธ ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ v6 ์‚ฌ์šฉ๋ฒ•

๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ 6.3.0 ๋ฒ„์ „์„ ์„ค์น˜

npm install react-router-dom@latest
//โ—๏ธ์ฐธ๊ณ ) ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ๋Š” ๋ฒ„์ „์— ๋”ฐ๋ผ ์‚ฌ์šฉ๋ฒ•์ด ๋‹ค๋ฅด๋‹ค.

๐Ÿ“œ BrowserRouter

History API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ๊ณ ์นจํ•˜์ง€ ์•Š๊ณ ๋„ ์ฃผ์†Œ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.
(์ฆ‰, UI๋ฅผ URL๊ณผ ๋™๊ธฐํ™”๋œ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•ด์ฃผ๋Š” ์—ญํ• )
์ƒ์œ„์— ์ž‘์„ฑ๋˜์–ด์•ผ React Router์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด ReactDOM์˜ ๋ Œ๋” ๋‹จ๊ณ„์ธ index.js ์—์„œ๋„ ํ™œ์šฉ ๊ฐ€๋Šฅ.

// index.js (React Version 18 ๊ธฐ์ค€)
import { BrowserRouter } from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

-----
// index.js (React Version 17 ๊ธฐ์ค€)
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(<BrowserRouter><App/></BrowserRouter>, document.querySelector('#root'));

๐Ÿ“œ Routes, Route

๊ฒฝ๋กœ๋ฅผ ๋งค์นญํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ.

โ–ท Routes
Route Configํ•˜๋Š” ๊ฒฝ๋กœ ๊ฐ์ฒด ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. Route๋Š” Routes์•ˆ์—์„œ๋งŒ ์œ ํšจํ•˜๋‹ค.
(Route๋กœ ์ƒ์„ฑ๋œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ ์ค‘์—์„œ ๋งค์นญ๋˜๋Š” ์ฒซ๋ฒˆ์งธ Route๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์—ญํ• )

โ–ท Route
path๊ฐ€ ํ˜„์žฌ URL๊ณผ ์ผ์น˜ํ•˜๋ฉด element๊ฐ€ ๋ Œ๋”๋ง ๋œ๋‹ค.

๋ผ์šฐํŒ… ์˜ˆ์ œ

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/MyPage" element={<MyPage />} />
    <Route path="/Dashboard" element={<Dashboard />} />
  </Routes>  
</BrowserRouter>

๐Ÿ“œ Link

ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ํด๋ฆญํ•  ๋•Œ, Route์˜ path์™€ ์ผ์น˜ํ•˜๋Š” ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ปดํฌ๋„ŒํŠธ์ด๋‹ค.

<Link to="path" />

๋งํฌ ์˜ˆ์ œ

import { BrowserRouter, Routes, Route, Link } from "react-router-dom"

function App() {
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/MyPage" element={<MyPage />} />
      <Route path="/Dashboard" element={<Dashboard />} />
    </Routes>  
  </BrowserRouter>
}

function Home() {
  return (
    <>
      <h1>Home</h1>
      <Link to="/MyPage">MyPage</Link> | <Link to="/Dashboard">Dashboard</Link>
    </>
  );
}

// MyPage ์ปดํฌ๋„ŒํŠธ
function MyPage() {
  return <h1>MyPage</h1>;
}

// Dashboard ์ปดํฌ๋„ŒํŠธ
function Dashboard() {
  return <h1>Dashboard</h1>;
}

export default App;

Link ์•ˆ์— ๋ฒ„ํŠผ์ด ์žˆ์œผ๋ฉด ํ‚ค๋ณด๋“œ๋กœ ํƒญ ํ–ˆ์„ ์‹œ ๋‘๋ฒˆ ์žกํžŒ๋‹ค.
ํ•œ๋ฒˆ๋งŒ ์žกํžˆ๊ฒŒ ํ•˜๋ ค๋ฉด ๋ฒ„ํŠผ์— tabIndex='-1'๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

<Link to='/signup'>
  <button className='signup' tabIndex='-1'>
    <div className='signup-bg'>
      <span>Sign up</span>
    </div>
  </button>
</Link>

๐Ÿ“œ Outlet

Outlet์€ ๋ผ์šฐํŒ…์ด ์ค‘์ฒฉ๋  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/MyPage" element={<MyPage />}>
      <Route path="/Dashboard" element={<DashboardPage />} />
    </Route>
  </Routes>  
</BrowserRouter>

-----
/* MyPage */
<div>
  <h1>MyPage</h1>
  <Link to="/MyPage/Dashboard">Dashboard<Link>
  <Outlet />  /* Dashboard์˜ component๊ฐ€ Outlet์˜ ์œ„์น˜์— ์œ„์น˜ํ•˜๊ฒŒ ๋œ๋‹ค. */
</div>

๐Ÿ“œ useLocation

pathname์„ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

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

const { pathname } = useLocation();

์ฟผ๋ฆฌ ์•Œ์•„๋‚ด๊ธฐ

const { search } = useLocation();
const query = new URLSearchParams(search).get('q');

๐Ÿ“œ useMatch

ํ˜„์žฌ ๊ฒฝ๋กœ์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ์•„๋‹Œ์ง€

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

const isInterestPage = useMatch('/interest');

๐Ÿ“œ useParams

ํŒŒ๋ผ๋ฏธํ„ฐ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€ ํ™œ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

/* App.js */   
<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/MyPage" element={<MyPage />} />
    <Route path="/Dashboard/:id" element={<DashboardPage />} />
  </Routes>  
</BrowserRouter>

-----
/* MyPage.js */   
return (
  <>
    {data.map(item => (
      <Link to={`/Dashboard/${item.id}`} key={item.id}>
        <h2>{item.title}</h2>
      </Link>
    ))}
  </>
)   
        
-----
/* DashboardPage.js */
const {id} = useParams();

return <div>DashboardPage {id}</div>

๐Ÿ“œ useNavigate

์–‘์‹์ด ์ œ์ถœ๋˜๊ฑฐ๋‚˜ ํŠน์ • event๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ, url์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” interface๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ

const navigate = useNavigate(); /* ๋ณ€์ˆ˜์— ์ €์žฅํ•ด์„œ ์‚ฌ์šฉ*/

return <h1 onClick={() => navigate("/")}>logo</h1>
/* ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด logo๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ฒŒ ๋จ */

๋’ค๋กœ๊ฐ€๊ธฐ / ์•ž์œผ๋กœ๊ฐ€๊ธฐ ์˜ˆ์‹œ

const navigate = useNavigate();

const goBack = () => {
  navigate(-1);
  // history.go(-1)
}

const goForward = () => {
  navigate(1);
  // history(1)
}

return (
  <>
    <button onClick={goBack}>๋’ค๋กœ๊ฐ€๊ธฐ</button>
    <button onClick={goForward}>์•ž์œผ๋กœ๊ฐ€๊ธฐ</button>
  </>
)

replace

navigate('/news/all', { replace: true });

๐Ÿ“œ ย  ย *ย ย ย 

๋งŒ์•ฝ ์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ •๋˜์ง€ ์•Š์€ ์ฃผ์†Œ๋กœ ์ ‘๊ทผํ•  ์‹œ ์ด ์†์„ฑ์ด ์„ค์ •๋˜์–ด ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์ฃผ๊ฒŒ ๋œ๋‹ค.

/* ์ƒ๋‹จ์— ์œ„์น˜ํ•˜๋Š” ๋ผ์šฐํŠธ๋“ค์˜ ๊ทœ์น™์„ ๋ชจ๋‘ ํ™•์ธ, ์ผ์น˜ํ•˜๋Š” ๋ผ์šฐํŠธ๊ฐ€ ์—†๋Š”๊ฒฝ์šฐ ์ฒ˜๋ฆฌ */
<Route path="*" element={<NotFound />}></Route>

๐Ÿ“œ useLocation

ํ˜„์žฌ URL ๊ฒฝ๋กœ ์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ํ•ด ์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
ํ˜„์žฌ ํŽ˜์ด์ง€์˜ ๊ฒฝ๋กœ๋ฅผ ํŒŒ์•…ํ•˜๊ฑฐ๋‚˜, ์ฟผ๋ฆฌ ์ŠคํŠธ๋ง ๋“ฑ URL์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

ํŽ˜์ด์ง€๋งˆ๋‹ค ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ์„ ๋‹ค๋ฅด๊ฒŒ ์ฃผ๊ณ  ์‹ถ์„ ๋•Œ ์˜ˆ์‹œ

/* GlobalStyle.js */
import { createGlobalStyle } from 'styled-components';
import { useLocation } from 'react-router-dom';

const GlobalStyled = createGlobalStyle`
  body {
    background-color: ${({ backgroundColor }) => backgroundColor || '#FFF'};
  }
`;

export function BackgroundColor() {
  const location = useLocation();
  let backgroundColor;
  switch (location.pathname) {
    case '/login':
    case '/signup':
      backgroundColor = '#F1F2F3';
      break;
    default:
      backgroundColor = '#FFF';
  }

  return <GlobalStyled backgroundColor={backgroundColor} />;
}
/* App.js */
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { BackgroundColor } from './GlobalStyle';

function App() {
  return (
    <>
      <BrowserRouter>
        <BackgroundColor /> // ์—ฌ๊ธฐ์— ์ถ”๊ฐ€ํ•จ
        <Routes>
          <Route ...>
        </Routes>
      </BrowserRouter>
    </>
  );
}

export default App;

์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ ์ถ”๊ฐ€์ ์ธ ์Šคํƒ€์ผ ๋˜๋Š” ํด๋ž˜์Šค๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ๋ฐฉ๋ฒ•

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

<NavLink
  to="/home"
  style={({ isActive }) => (isActive ? { opacity: 1 } : {})}
>
  Home
</NavLink>

styled-components์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

const StyledLink = styled(NavLink)`
  text-decoration: none;
  margin-right: 78px;

  &:last-of-type {
    margin-right: 0;
  }

  span {
    color: var(--white-100);
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: 600;
    font-size: 16px;
    opacity: 0.6;
  }

  &.active span {   ~~~์ด ๋ถ€๋ถ„์ž„~~~
    opacity: 1;
  }

  button {
    display: flex;
    justify-content: center;
    align-items: center;
  }
`;

.....
<StyledLink to={`/feed/${groupId}`}>
  <button>
    <span>Feed</span>
  </button>
</StyledLink>

๐Ÿ“œ query

const navigate = useNavigate();

navigate(`/search?q=${query}`);
const location = useLocation();

const { search } = useLocation();
const query = new URLSearchParams(search).get('q');



๐Ÿ‘‰ React-Router ๊นƒํ—™
๐Ÿ‘‰ React Router ๊ณต์‹ ๋ฌธ์„œ

profile
๐Ÿพ

0๊ฐœ์˜ ๋Œ“๊ธ€