React Router

woomยท2023๋…„ 6์›” 13์ผ
0

React

๋ชฉ๋ก ๋ณด๊ธฐ
4/9
post-thumbnail

์ถœ์ฒ˜ : ํŒจ์ŠคํŠธ์บ ํผ์Šค ํ•œ ๋ฒˆ์— ๋๋‚ด๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ ์ดˆ๊ฒฉ์ฐจ ํŒจํ‚ค์ง€


๐Ÿ“• SPA ๋ผ์šฐํŒ… ๊ณผ์ •

  • SPA(Single Page Application) : ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ํ•˜๋‚˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐ›์•„์„œ ๋‚ด๋ถ€์—์„œ url์— ๋งž์ถฐ ๋ณด์—ฌ์ฃผ๋Š” ํ˜•์‹ (์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๊ฐ๊ฐ์˜ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ฒƒ๊ณผ ์ฐจ์ด)
  1. ๋ธŒ๋ผ์šฐ์ €์— ์ตœ์ดˆ์— '/'๊ฒฝ๋กœ๋กœ ์š”์ฒญ์„ ํ•˜๋ฉด, React Web App์„ ๋‚ด๋ ค์คŒ
  2. ๋‚ด๋ ค๋ฐ›์€ React App์—์„œ '/'๊ฒฝ๋กœ์— ๋งž๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์คŒ
  3. React App์—์„œ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ์ƒˆ๋กœ์šด ๊ฒฝ๋กœ์— ๋งž๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์คŒ

๐Ÿ“™ Static ๋ผ์šฐํŒ…

  • react-router-dom v6 ์—…๋ฐ์ดํŠธ ํ›„ ๋‹ฌ๋ผ์ง„ ์  : https://kyung-a.tistory.com/36 ์ฐธ๊ณ 

  • react project์—์„œ ๋ผ์šฐํŒ… ํŒจํ‚ค์ง€ ์„ค์น˜(๊ธฐ๋ณธ ๋‚ด์žฅ๋œ ํŒจํ‚ค์ง€ ์•„๋‹˜)

    • npm i react-router-dom

๐Ÿฃ ์‹คํ–‰์˜ˆ์ œ

  • / : Home ์ปดํฌ๋„ŒํŠธ
  • /profile : Profile ์ปดํฌ๋„ŒํŠธ
  • /about : About ์ปดํฌ๋„ŒํŠธ

App.js
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "./pages/Home";
import Profile from "./pages/Profile";
import About from "./pages/About";
// react-router-dom version6์ด์ƒ๋ถ€ํ„ฐ <Route>๋ฅผ <Routes>์•ˆ์— ๊ฐ์‹ธ์ค˜์•ผํ•จ
function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/profile" element={<Profile />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;


Home.jsx
export default function Home() {
  return <div>Home Page</div>;
}


๐Ÿ“’ Dynamic ๋ผ์šฐํŒ…

  1. ์ง€์ •๋œ ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์„ ์ „๋‹ฌํ•˜์—ฌ ์ถœ๋ ฅ (id, typeof)
  • App.js์—์„œ ๊ฒฝ๋กœ๊ฐ’ ์„ค์ • : /:ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’/*

๐Ÿฃ ์‹คํ–‰์˜ˆ์ œ (๊ฒฝ๋กœ๊ฐ’์ง€์ •)

์ฐธ๊ณ ๐Ÿ’ก {์กฐ๊ฑด && expression} ์€ ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง์œผ๋กœ ์กฐ๊ฑด์ด ์ฐธ์ผ ๊ฒฝ์šฐ์—๋งŒ ํ‘œํ˜„์‹์ด ์‹คํ–‰๋œ๋‹ค.

import { useParams } from "react-router-dom";

export default function Profile() {
  const { id } = useParams();
  console.log(id, typeof id);

  return (
    <div>
      <h2>Profile Page</h2>
      {id && <p>id is {id}. </p>}
    </div>
  );
}

  1. ์ฟผ๋ฆฌ์ŠคํŠธ๋ง๊ฐ’์œผ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’ ์ „๋‹ฌํ•˜์—ฌ ์ถœ๋ ฅ (name=mark)
  • const searchParam = useLocation()์—์„œ searchParam์˜ search๊ฐ’์ด ?name=markํ™•์ธ

๐Ÿฃ ์‹คํ–‰์˜ˆ์ œ (์ฟผ๋ฆฌ์ŠคํŠธ๋ง)

์ฐธ๊ณ ๐Ÿ’ก URLSearchParams ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด npm i query-string ์„ค์น˜

import { useLocation } from "react-router-dom";
import queryString from "query-string";

export default function About() {
  const searchParam = useLocation().search;
  console.log(searchParam); //?name=mark
  const query = queryString.parse(searchParam);
  console.log(query); //{name: "mark"}

  return (
    <div>
      <h2>About Page</h2>
      {query.name && <p>name์€ {query.name} ์ž…๋‹ˆ๋‹ค.</p>}
    </div>
  );
}

๐Ÿ“Œ NotFound

  • ์ง€์ •๋œ ๊ฒฝ๋กœ๊ฐ€ ์•„๋‹ ๊ฒฝ์šฐ notfound์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋จ
    • ์œ„์˜ ๊ฒฝ๋กœ๋ฅผ ๋‹ค ๋น„๊ตํ•ด๋ณด๊ณ  ๋ชจ๋‘ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์‹คํ–‰๋จ
      => path="*" ๋Š” ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ํฌํ•จํ•˜๊ธฐ ๋•Œ๋ฌธ
export default function NotFound() {
  return <div>ํŽ˜์ด์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.</div>;
}

๐Ÿ“— JSX๋งํฌ๋กœ ๋ผ์šฐํŒ… ์ด๋™

  • ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ƒˆ๋กœ์šด ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ด๋ฏธ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” react view์ค‘์—์„œ ์•Œ๋งž๋Š” view๋ฅผ ๋ณด์—ฌ์คŒ
    • ๋กœ๋”ฉ ์—†์ด ๋น ๋ฅด๊ฒŒ view ์ „ํ™˜ ๊ฐ€๋Šฅ
    • Link์ปดํฌ๋„ŒํŠธ์˜ to์†์„ฑ ์ด์šฉ
import { Link } from "react-router-dom";
export default function Links() {
  return (
    <ul>
      <li>
        <Link to="/">Home</Link>
      </li>
      <li>
        <Link to="/profile">Profile</Link>
      </li>
      <li>
        <Link to="/profile/1">Profile/1</Link>
      </li>
      <li>
        <Link to="/about">About</Link>
      </li>
      <li>
        <Link to="/about?name=woom">About?name=woom</Link>
      </li>
    </ul>
  );
}

  • activeClassName, activeSyle ์ฒ˜๋Ÿผ active ์ƒํƒœ์— ๋Œ€ํ•œ ์Šคํƒ€์ผ ์ง€์ • ๊ฐ€๋Šฅ
  • Route์˜ path์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— end(๊ตฌ: exact)๊ฐ€ ์žˆ์Œ
  • v6 ๋ณ€๊ฒฝ์‚ฌํ•ญ (์ฐธ๊ณ  : https://seungahhong.github.io/blog/2022/03/2022-03-12-react-router-v6/)

import { NavLink, useLocation } from "react-router-dom";

export default function NavLinks() {
  const activeStyle = { color: "red" };
  const location = useLocation();

  return (
    <ul>
      <li>
        <NavLink to="/" style={({ isActive }) => (isActive ? activeStyle : {})}>
          Home
        </NavLink>
      </li>
      <li>
        <NavLink
          to="/profile"
          end
          style={({ isActive }) => (isActive ? activeStyle : {})}>
          Profile
        </NavLink>
      </li>
      <li>
        <NavLink
          to="/profile/1"
          style={({ isActive }) => (isActive ? activeStyle : {})}>
          Profile/1
        </NavLink>
      </li>
      <li>
        <NavLink
          to="/about"
          style={location.pathname === "/about" ? activeStyle : {}}>
          About
        </NavLink>
      </li>
      <li>
        <NavLink
          to="/about?name=woom"
          style={location.search === "?name=woom" ? activeStyle : {}}>
          About?name=woom
        </NavLink>
      </li>
    </ul>
  );
}

๐Ÿ“˜ JS๋กœ ๋ผ์šฐํŒ… ์ด๋™

๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ (LoginButton Component์‚ฌ์šฉ)

import LoginButton from "../components/LoginButton";

export default function Login(props) {
  return (
    <div>
      <h2>Login Page</h2>
      <LoginButton />
    </div>
  );
}

LoginButton Component

  • navigate() : ํŽ˜์ด์ง€ ์ด๋™
    • login๋ฒ„ํŠผ ํด๋ฆญํ•˜๋ฉด 1์ดˆ ํ›„์— "/"ํŽ˜์ด์ง€๋กœ ์ด๋™
import { useNavigate } from "react-router-dom";

export default function LoginButton(props) {
  console.log(props);
  const navigate = useNavigate();
  function login() {
    setTimeout(() => {
      navigate("/");
    }, 1000);
  }
  return <button onClick={login}>Log in</button>;
}

๐Ÿ“Œ Redirect๊ธฐ๋Šฅ Navigate (v6)


profile
Study Log ๐Ÿ“‚

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

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด