React Router

LEE GYUHOยท2023๋…„ 10์›” 29์ผ
1

๐Ÿ“ŒReact Router๋กœ ์›น์‚ฌ์ดํŠธ ๋งŒ๋“ค๊ธฐ

  • ๐Ÿ“˜๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ
    ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ํŽ˜์ด์ง€๋ฅผ ๋‚˜๋ˆ„๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

    • Router: ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๋“ค์„ ๋ชจ๋‘ ๊ฐ–๊ณ  ์žˆ๋Š” ๋…€์„์ด๋‹ค.
      ํ˜„์žฌ ์ฃผ์†Œ๋‚˜ ํŽ˜์ด์ง€ ๊ธฐ๋ก ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ด๊ฒŒ ์—†์œผ๋ฉด ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ๋ฅผ ์“ธ ์ˆ˜ ์—†๋‹ค.
      ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ ๋ผ์šฐํ„ฐ ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

    • Routes, Route: ์ด ๋‘ ์ปดํฌ๋„ŒํŠธ๋Š” ์ฃผ๋กœ ๊ฐ™์ด ์‚ฌ์šฉ๋œ๋‹ค. Routes ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ Route ์ปดํฌ๋„ŒํŠธ๋กœ ํŽ˜์ด์ง€์˜ ๊ฒฝ๋กœ, ๋ณด์—ฌ์ค„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ง€์ •ํ•œ๋‹ค. ์ฐจ๋ก€๋Œ€๋กœ ๊ฒฝ๋กœ๋ฅผ ์‚ดํŽด๋ณด๋‹ค๊ฐ€ ๋งž๋Š” ๊ฒฝ๋กœ๋ฅผ ์ฐพ์œผ๋ฉด ๊ทธ ์•ˆ์—์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

    • Link: ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ์—์„œ aํƒœ๊ทธ ๋Œ€์‹  ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ด๋‹ค.
  • ๐Ÿ“˜ํŽ˜์ด์ง€ ๋‚˜๋ˆ„๋Š” ๋ฐฉ๋ฒ•
    Routes ์ปดํฌ๋„ŒํŠธ ์•ˆ์—๋‹ค๊ฐ€ Route ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐฐ์น˜ํ•ด์„œ ๊ฐ ํŽ˜์ด์ง€๋ฅผ ๋‚˜๋ˆ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ์ด๋•Œ Routes ์•ˆ์—์„œ๋Š” ์œ„์—์„œ๋ถ€ํ„ฐ ์ฐจ๋ก€๋Œ€๋กœ Route๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š”๋ฐ์š”.
    ํ˜„์žฌ ๊ฒฝ๋กœ์™€ path prop์ด ์ผ์น˜ํ•˜๋Š” Route ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

<Routes>
  <Route path="/" element={<HomePage />} />
  <Route path="posts" element={<PostListPage />} />
  <Route path="posts/1" element={<PostPage />} />
</Routes>
  • ๐Ÿ“˜๋งํฌ
    ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ์—์„œ๋Š” a ํƒœ๊ทธ ๋Œ€์‹ ์— Link ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    to ๋ผ๋Š” prop์œผ๋กœ ์ด๋™ํ•  ๊ฒฝ๋กœ๋ฅผ ์ •ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
<Link to="/posts">๋ธ”๋กœ๊ทธ</Link>
  • ๐Ÿ“˜ํ•˜์œ„ ํŽ˜์ด์ง€ ๋‚˜๋ˆ„๊ธฐ
    Route ์ปดํฌ๋„ŒํŠธ ์•ˆ์—๋‹ค๊ฐ€ Route ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐฐ์น˜ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
    ์ด๋•Œ ํ•˜์œ„ ํŽ˜์ด์ง€์—์„œ ์ตœ์ƒ์œ„ ๊ฒฝ๋กœ์— ํ•ด๋‹นํ•˜๋Š” ๊ฒฝ๋กœ๋Š” path prop์ด ์•„๋‹ˆ๋ผ
    index ๋ผ๋Š” prop์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
<Routes>
  <Route path="/"><HomePage /></Route>
  <Route path="posts" element={<PostLayout />} >
    <Route index element={<PostListPage />}  />
    <Route path="1" element={<PostPage />}  />
  </Route>
</Routes>

์ด๋•Œ ๋ถ€๋ชจ Route ์ปดํฌ๋„ŒํŠธ์— element ๋ฅผ ์ง€์ •ํ•˜๊ณ ,
์•„๋ž˜์ฒ˜๋Ÿผ Outlet ์ด๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๊ณตํ†ต๋œ ๋ ˆ์ด์•„์›ƒ์„ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ์—ˆ์ฃ .

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

function PostLayout() {
  return (
    <div>
      <h1>๋ธ”๋กœ๊ทธ</h1>
      <hr />
      <Outlet />
    </div>
  );
}

export default PostLayout;
  • ๐Ÿ“˜๋™์ ์ธ ๊ฒฝ๋กœ ๋‹ค๋ฃจ๊ธฐ
    ์ฝœ๋ก  (:) ์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒฝ๋กœ์— ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
    ์˜ˆ๋ฅผ๋“ค์–ด์„œ ์•„๋ž˜์ฒ˜๋Ÿผ /posts/:postId ๋ผ๋Š” ๊ฒฝ๋กœ๋Š” /posts/123 ์ด๋ผ๋˜์ง€
    /posts/abc ๋ผ๋Š” ์ฃผ์†Œ๋กœ ์ ‘์†ํ•˜๋ฉด 123 ์ด๋‚˜ abc ๋ผ๋Š” ๊ฐ’์„ postId ๋ผ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.
<Routes>
  <Route path="/"><HomePage /></Route>
  <Route path="posts" element={<PostLayout />} >
    <Route index element={<PostListPage />}  />
    <Route path=":postId" element={<PostPage />}  />
  </Route>
</Routes>

๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด useParams ๋ผ๋Š” ํ›…์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

function PostPage() {
  const { postId } = useParams();
  // ...
}
  • ๐Ÿ“˜์ฟผ๋ฆฌ ์‚ฌ์šฉํ•˜๊ธฐ
    useSearchParams ๋ผ๋Š” Custom hook์œผ๋กœ SearchParams ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋Š”๋ฐ์š”.
    ์ด hook์€ SearchParams ๊ฐ์ฒด์™€ Setter ํ•จ์ˆ˜๋ฅผ ๋ฐฐ์—ดํ˜•์œผ๋กœ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.
    ์ด๋•Œ ์ฟผ๋ฆฌ ๊ฐ’์€ SearchParams ์˜ get ํ•จ์ˆ˜๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
import { useSearchParams } from 'react-router-dom';

function PostListPage() {
  const [searchParams, setSearchParams] = useSearchParams();
  const filterQuery = searchParams.get('filter');

  // ...
}

๋งŒ์•ฝ ์ฟผ๋ฆฌ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์ฃผ์†Œ๋ฅผ ์ด๋™ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด Setter ํ•จ์ˆ˜์— ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
์ด๋•Œ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋กœ ์ฟผ๋ฆฌ ๊ฐ’์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•„๋ž˜ ์˜ˆ์‹œ๋Š” ?filter=react ๋ผ๋Š” ์ฟผ๋ฆฌ๋กœ ์ด๋™ํ•˜๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

setSearchParams({
  filter: 'react',
});
  • ๐Ÿ“˜ํŽ˜์ด์ง€ ์ด๋™ํ•˜๊ธฐ

    • Navigate ์ปดํฌ๋„ŒํŠธ
      ๋ฆฌํ„ด๊ฐ’์œผ๋กœ Navigate ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฆฌํ„ดํ•˜๋ฉด to prop์œผ๋กœ ์ง€์ •ํ•œ ๊ฒฝ๋กœ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
    function PostPage() {
    // ...
    
      const post = getPost(postId);
    
      // post๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ /posts ํŽ˜์ด์ง€๋กœ ์ด๋™
      if (!post) {
        return <Navigate to="/posts" />;
      }
    
      // ...
    }
    • useNavigate Hook
      useNavigate ๋ผ๋Š” hook์œผ๋กœ navigate ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ์ด ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    const navigate = useNavigate();
    
    const handleClick = () => {
      // ... ์–ด๋–ค ์ž‘์—…์„ ํ•œ ๋‹ค์Œ์— ํŽ˜์ด์ง€๋ฅผ ์ด๋™
      navigate('/wishlist');
    }
  • ๐Ÿ“˜Link, Navigate, useNavigate๋Š” ์–ธ์ œ ์“ฐ๋Š”๊ฒŒ ์ข‹์„๊นŒ?
    ์„ธ ๊ฐ€์ง€ ๋ชจ๋‘ ๋‹ค ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•  ๋•Œ ์“ธ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ๋น„์Šทํ•œ๋ฐ์š”.
    ์ด๊ฒƒ๋“ค์„ ์–ธ์ œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„์ง€ ์˜ˆ์‹œ๋ž‘ ๊ฐ™์ด ํ•œ๋ฒˆ ์‚ดํŽด๋ด…์‹œ๋‹ค.

    • Link
      ์‚ฌ์šฉ์ž๊ฐ€ ํด๋ฆญํ•ด์„œ ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•˜๋„๋ก ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
      ํ•˜์ดํผ๋งํฌ ํ…์ŠคํŠธ๋‚˜ ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•˜๋Š” ๋ฒ„ํŠผ, ์ด๋ฏธ์ง€ ๋“ฑ์— ์‚ฌ์šฉํ•˜๋ฉด ๋˜๊ฒ ์ฃ ?
      ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ Link ๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

    • Navigate
      ํŠน์ • ๊ฒฝ๋กœ์—์„œ ๋ Œ๋”๋ง ์‹œ์ ์— ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™์‹œํ‚ค๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

      ์˜ˆ์‹œ:
      ์‡ผํ•‘๋ชฐ์˜ ํšŒ์› ์ „์šฉ ํŽ˜์ด์ง€์— ๋กœ๊ทธ์ธ์—†์ด ๋“ค์–ด์™€์„œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜๋Š” ๊ฒฝ์šฐ

      ์‡ผํ•‘๋ชฐ์˜ ์ƒํ’ˆ ์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ ์ œํ’ˆ์ด ํ’ˆ์ ˆ๋˜์—ˆ๊ฑฐ๋‚˜ ์‚ญ์ œ๋˜์–ด์„œ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™์‹œํ‚ค๋Š” ๊ฒฝ์šฐ

    • useNavigate
      ํŠน์ •ํ•œ ์ฝ”๋“œ์˜ ์‹คํ–‰์ด ๋๋‚˜๊ณ  ๋‚˜์„œ ํŽ˜์ด์ง€๋ฅผ ์ด๋™์‹œํ‚ค๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

      ์˜ˆ์‹œ:
      ์‡ผํ•‘๋ชฐ์—์„œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด๊ธฐ๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ๋ณด๋‚ด๊ณ  ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€๋กœ ์ด๋™์‹œํ‚ค๋Š” ๊ฒฝ์šฐ

      ์‡ผํ•‘๋ชฐ์—์„œ ๊ฒฐ์ œํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ณ  ๋‚˜์„œ ๋ชจ๋“  ๊ฒฐ์ œ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„์— ํŽ˜์ด์ง€๋ฅผ ์ด๋™์‹œํ‚ค๋Š” ๊ฒฝ์šฐ

      ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€์—์„œ ๋กœ๊ทธ์ธ์„ ์™„๋ฃŒํ•œ ํ›„์— ์ฒ˜์Œ ์ง„์ž…ํ–ˆ๋˜ ํŽ˜์ด์ง€๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ฒฝ์šฐ

profile
๋ˆ„๊ตฌ๋‚˜ ๊ฐ™์€ ํŒ€์œผ๋กœ ๋˜๊ธธ ๋ฐ”๋ผ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์ž

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