๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

javascript/[TIL] ๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ 

๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ  - ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ๋กœ SPA ๊ฐœ๋ฐœํ•˜๊ธฐ

728x90

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ผ์šฐํŒ…์ด๋ž€?

๋ผ์šฐํŒ… : ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญํ•œ URL์— ๋”ฐ๋ผ ์•Œ๋งž์€ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ

 

์—ฌ๋Ÿฌ ํŽ˜์ด์ง€๋กœ ๊ตฌ์„ฑ๋œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ๋•Œ, ํŽ˜์ด์ง€ ๋ณ„๋กœ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๋ถ„๋ฆฌํ•ด๊ฐ€๋ฉด์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ ๋ผ์šฐํŒ… ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค.

 

๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ, Next.js ๋ฆฌ์—‘ํŠธ์—์„œ ๋ผ์šฐํŒ… ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

- ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ : ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ผ์šฐํŒ… ์‹œ์Šคํ…œ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

- Next.js : ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ์˜ ํ”„๋ ˆ์ž„์›Œํฌ, ์ด ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๋ผ์šฐํŒ… ์‹œ์Šคํ…œ์€ ํŒŒ์ผ ๊ฒฝ๋กœ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘๋™

๋ผ์šฐํŒ… ๊ด€๋ จ ๊ธฐ๋Šฅ์€ ๋ฆฌ์•กํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์„œ๋“œ ํŒŒํ‹ฐ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

* ์„œ๋“œ ํŒŒํ‹ฐ๋ž€?

ํŽธํ•˜๊ณ  ํšจ์œจ์ ์ธ ๊ฐœ๋ฐœ์„ ์œ„ํ•ด, ํ”Œ๋Ÿฌ๊ทธ์ธ์ด๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, ์ œ์ž‘์‚ฌ์—์„œ ๋งŒ๋“ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์—…์ฒด์—์„œ ๋งŒ๋“  ํ•ด๋‹น ํˆด ์ง€์› ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ.


 

์‹ฑ๊ธ€ ํŽ˜์ด์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜

: ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€๋กœ ์ด๋ฃจ์–ด์ง„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜

์ด๋ ‡๊ฒŒ html์€ ํ•œ ๋ฒˆ ๋งŒ ๋ฐ›์•„์™€์„œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰์‹œํ‚จ ํ›„, ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ๋ฐ›์•„์™€ ํ™”๋ฉด์— ์—…๋ฐ์ดํŠธํ•˜๋Š”๊ฒƒ

↔ ๋ฉ€ํ‹ฐ ํŽ˜์ด์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ : ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด html์„ ๋ฐ›์•„์˜ค๊ณ , ํŽ˜์ด์ง€๋ฅผ ๋กœ๋”ฉํ•  ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„์—์„œ css, js, ์ด๋ฏธ์ง€ ํŒŒ์ผ ๋“ฑ์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ ๋ธŒ๋ผ์šฐ์ €์— ๋ณด์—ฌ์คŒ.

๊ฐ ํŽ˜์ด์ง€๋งˆ๋‹ค ๋‹ค๋ฅธ html ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ ์ œ๊ณตํ•˜๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ์— ๋”ฐ๋ผ ์œ ๋™์ ์ธ html์„ ์ƒ์„ฑํ•ด์ฃผ๋Š” ํ…œํ”Œ๋ฆฟ ์—”์ง„์„ ์‚ฌ์šฉ

 

 

์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜์ด ๋งŽ๊ณ  ๋‹ค์–‘ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฒฝ์šฐ, ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ค˜์•ผ ํ•  ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„์ธก์—์„œ ๋ถ€๋‹ด์„ ์คŒ.

-> ๊ทธ๋ž˜์„œ ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ๋ทฐ ๋ Œ๋”๋ง์„ ์‚ฌ์šฉ์ž์˜ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋‹ด๋‹นํ•˜๋„๋ก ํ•˜๊ณ , ์ธํ„ฐ๋ž™์…˜์ด ๋ฐœ์ƒํ•˜๋ฉด ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋์Šต๋‹ˆ๋‹ค. (ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์ƒˆ๋กœ ๋ถˆ๋Ÿฌ์™€ ์‚ฌ์šฉ)

 

๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ๋•Œ ์„œ๋ฒ„์— ๋‹ค๋ฅธ ํŽ˜์ด์ง€์˜ html์„ ์ƒˆ๋กœ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ,

๋ธŒ๋ผ์šฐ์ €์˜ History API๋ฅผ ์‚ฌ์šฉํ•ด ๋ธŒ๋ผ์šฐ์ €์˜ ์ฃผ์†Œ์ฐฝ์˜ ๊ฐ’๋งŒ ๋ณ€๊ฒฝํ•˜๊ณ 

๊ธฐ์กด์— ํŽ˜์ด์ง€์— ๋„์› ๋˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋ฉด์„œ ๋ผ์šฐํŒ… ์„ค์ •์— ๋”ฐ๋ผ ๋˜ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


<BrowserRouter>

ํ”„๋กœ์ ํŠธ์— ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ๋ฅผ ์ ์šฉํ• ๋Œ„ BrowserRouter๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ์‹ธ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ด ์ปดํฌ๋„ŒํŠธ๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— HTML5์˜ Histroy API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ ๋ถˆ๋Ÿฌ์˜ค์ง€ ์•Š๊ณ ๋„ ์ฃผ์†Œ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ํ˜„์žฌ ์ฃผ์†Œ์˜ ๊ฒฝ๋กœ์— ๊ด€๋ จ๋œ ์ •๋ณด๋ฅผ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค.

 

<Route> ์ปดํฌ๋„ŒํŠธ

: ํŠน์ • ๊ฒฝ๋กœ(์ฃผ์†Œ)์— ์›ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ๋ณด์—ฌ์ฃผ๊ธฐ

<Route path="์ฃผ์†Œ ๊ทœ์น™" elemet={๋ณด์—ฌ ์ค„ ์ปดํฌ๋„ŒํŠธ JSX}/>   

<Route path="/about" element={<About />} />

 

<Link> ์ปดํฌ๋„ŒํŠธ

: ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ๋งํฌ ๋ณด์—ฌ์ฃผ๊ธฐ

๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์—์„œ๋Š” <a> ํƒœ๊ทธ๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

์™œ๋ƒํ•˜๋ฉด <a> ํƒœ๊ทธ๋กœ ํŽ˜์ด์ง€๋ฅผ ์ด๋™์‹œ, ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Link ์ปดํฌ๋„ŒํŠธ๋„ <a>ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธด ํ•˜์ง€๋งŒ,

ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์„ ๋ง‰๊ณ , Histroy API๋ฅผ ํ†ตํ•ด ๋ธŒ๋ผ์šฐ์ € ์ฃผ์†Œ์˜ ๊ฒฝ๋กœ๋งŒ ๋ฐ”๋€Œ๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

<Link to="๊ฒฝ๋กœ"> ๋งํฌ ์ด๋ฆ„</Link>   

<Link to="/about"> ์†Œ๊ฐœ </Link> 

 


URL ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ์ฟผ๋ฆฌ์ŠคํŠธ๋ง

ํŽ˜์ด์ง€ ์ฃผ์†Œ๋ฅผ ์ •์˜ํ•  ๋•Œ ๊ฐ€๋”์€ ์œ ๋™์ ์ธ ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

- URL ํŒŒ๋ผ๋ฏธํ„ฐ

: ์ฃผ์†Œ์˜ ๊ฒฝ๋กœ์— ์œ ๋™์ ์ธ ๊ฐ’์„ ๋„ฃ๋Š” ํ˜•ํƒœ, ์ฃผ๋กœ ID๋˜๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ ์‚ฌ์šฉ

- ์ฟผ๋ฆฌ์ŠคํŠธ๋ง

: ์ฃผ์†Œ์˜ ๋’ท๋ถ€๋ถ„์— ' ? '๋ฌธ์ž์—ด ์ดํ›„์— key=value๋กœ ๊ฐ’์„ ์ •์˜ํ•˜๋ฉฐ &๋กœ ๊ตฌ๋ถ„ํ•˜๋Š” ํ˜•ํƒœ, ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰, ํŽ˜์ด์ง€๋„ค์ด์…˜, ์ •๋ ฌ ๋ฐฉ์‹ ๋“ฑ ๋ฐ์ดํ„ฐ ์กฐํšŒ์— ํ•„์š”ํ•œ ์˜ต์…˜์„ ์ „๋‹ฌํ•  ๋•Œ ์‚ฌ์šฉ

 

- URL ํŒŒ๋ผ๋ฏธํ„ฐ

useParams : ์ด Hook์„ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 
Profile.js

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

const data = {
  velopert: {
    name: "๊น€๋ฏผ์ค€",
    description: "๋ฆฌ์•กํŠธ๋ฅผ ์ข‹์•„ํ•˜๋Š” ๊ฐœ๋ฐœ์ž",
  },
  gildong: {
    name: "ํ™๊ธธ๋™",
    description: "๊ณ ์ „ ์†Œ์„ค ์ฃผ์ธ๊ณต",
  },
};

const Profile = () => {
  /* URL ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” useParams๋ผ๋Š” Hook์„ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์กฐํšŒ ๊ฐ€๋Šฅ */
  const params = useParams();
  /*username URL ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ†ตํ•˜์—ฌ ํ”„๋กœํ•„์„ ์กฐํšŒ*/
  const profile = data[params.username];
  console.log("profile", profile); /* 'veloper' or 'gildong' */
  return (
    <div>
      <h1>์‚ฌ์šฉ์ž ํ”„๋กœํ•„</h1>
      {profile ? (
        <div>
          <h2>{profile.name}</h2>
          <p>{profile.description}</p>
        </div>
      ) : (
        <p>์กด์žฌํ•˜์ง€ ์•Š๋Š” ํ”„๋กœํ•„์ž…๋‹ˆ๋‹ค.</p>
      )}
    </div>
  );
};
export default Profile;

 
App.js

import
{ Route, Routes } from "react-router-dom";
import "./App.css";
import Home from "./pages/Home";
import Profile from "./pages/Profile";

function App() {
  return (
    <Routes>
        <Route index element={<Home />} />
        {/* URL ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์ด๋ฆ„์€ ๋ผ์šฐํ„ฐ๋ฅผ ์„ค์ •ํ•  ๋•Œ Route ์ปดํฌ๋„ŒํŠธ์˜ path props๋ฅผ ํ†ตํ•ด ์„ค์ • */}
        <Route path="/profiles/:username" element={<Profile />} />
       
    </Routes>
  );
}

export default App;
Home.js

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

const Home = () => {
  return (
    <div>
      <ul>
        <li>
          <Link to="/about">์†Œ๊ฐœ</Link>
        </li>
        <li>
          <Link to="/profiles/velopert">velopert์˜ ํ”„๋กœํ•„</Link>
        </li>
        <li>
          <Link to="/profiles/gildong">gildong์˜ ํ”„๋กœํ•„</Link>
        </li>
        <li>
          <Link to="/profiles/void">์กด์žฌํ•˜์ง€ ์•Š๋Š” ํ”„๋กœํ•„</Link>
        </li>
        <li>
          <Link to="/articles">๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก</Link>
        </li>
      </ul>
    </div>
  );
};
export default Home;


- ์ฟผ๋ฆฌ์ŠคํŠธ๋ง

useSearchParams๋ผ๋Š” ์ด Hook์„ ํ†ตํ•ด, ๋ฌธ์ž์—ด์„ ๋ถ„๋ฆฌํ•œ ๋’ค key์™€ value๋กœ ํŒŒ์‹ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

useSearchParams๋Š” ๋ฐฐ์—ด ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜,

์ฒซ ๋ฒˆ์งธ ์›์†Œ(searchParams)๋Š” ์ฟผ๋ฆฌํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์กฐํšŒ(get)*์ˆ˜์ •(set)ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋“ค์ด ๋‹ด๊ธด ๊ฐ์ฒด ๋ฐ˜ํ™˜

๋งŒ์•ฝ ์กฐํšŒ ์‹œ ์ฟผ๋ฆฌํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด -> null๋กœ ์กฐํšŒ๋จ.
๋‘๋ฒˆ์งธ ์›์†Œ(setSearchParams)๋Š” ์ฟผ๋ฆฌํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜

About.js

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

const About = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const detail = searchParams.get("detail");
  const mode = searchParams.get("mode");

  const onToggleDetail = () => {
    setSearchParams({ mode, detail: detail === "true" ? false : true });
  };

  const onIncreaseMode = () => {
    const nextMode = mode === null ? 1 : parseInt(mode) + 1;
    setSearchParams({ mode: nextMode, detail });
  };

  return (
    <div>
      <h1>์†Œ๊ฐœ</h1>
      <p>๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด๋Š” ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค.</p>
      <p>detail: {detail}</p>
      <p>mode: {mode}</p>

      <button onClick={onToggleDetail}> toggle detail</button>
      <button onClick={onIncreaseMode}> increase mode</button>
    </div>
  );
};
export default About;

์ค‘์ฒฉ๋œ ๋ผ์šฐํŠธ

์ค‘์ฒฉ๋œ ๋ผ์šฐํŠธ๋ฅผ ํ†ตํ•ด ๊ณตํ†ต ๋ ˆ์ด์•„์›ƒ ์ปดํฌ๋„ŒํŠธ๋กœ, ํŽ˜์ด์ง€๋ผ๋ฆฌ ๊ณตํ†ต์ ์œผ๋กœ ๋ณด์—ฌ์ค˜์•ผ ํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ์„ ํ‘œํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์ค‘์ฒฉ๋œ ๋ผ์šฐํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•œ๋ฒˆ๋งŒ ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

 

<Outlet> ์ปดํฌ๋„ŒํŠธ

: Route์˜ children์œผ๋กœ ๋“ค์–ด๊ฐ€๋Š” JSX ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• 

 

index props

์ด props๋Š” path="/"์™€ ๋™์ผํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„๋‹ค.

Layout.js

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

const Layout = () => {

  return (
    <div>
      <header style={{ background: "lightgreen", padding: 16, fontSize: 24 }}>
        <button onClick={goBack}>๋’ค๋กœ๊ฐ€๊ธฐ</button>
        <button onClick={goArticle}>๊ฒŒ์‹œ๊ธ€๋กœ ๊ฐ€๊ธฐ</button>
      </header>
      <main>
        <Outlet />
      </main>
    </div>
  );
};
export default Layout;
App.js

import
{ Route, Routes } from "react-router-dom";
import "./App.css";
import About from "./pages/About";
import Article from "./pages/Article";
import Articles from "./pages/Articles";
import Home from "./pages/Home";
import Layout from "./pages/Layout";
import Profile from "./pages/Profile";

function App() {
  return (
    <Routes>
      <Route element={<Layout />}>
        <Route index element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/profiles/:username" element={<Profile />} />
        <Route path="/articles" element={<Articles />}>
          <Route path="/articles/:id" element={<Article />} />
        </Route>
      </Route>
    </Routes>
  );
}

export default App;

 


๋ฆฌ์—‘ํŠธ ๋ผ์šฐํ„ฐ ๋ถ€๊ฐ€๊ธฐ๋Šฅ

 

1. useNavigate 

: Link ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ์ƒํ™ฉ์— ์‚ฌ์šฉํ•˜๋Š” Hook

 

+ replace props

: ์ด ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•  ๋•Œ ํ˜„์žฌ ํŽ˜์ด์ง€๋ฅผ ํŽ˜์ด์ง€ ๊ธฐ๋ก์— ๋‚จ๊ธฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

→ ๋’ค๋กœ ๊ฐ€๊ธฐ๋ฅผ ๋ˆŒ๋ €์„๋•Œ navigation(-2)

import { Outlet, useNavigate } from "react-router-dom";

const Layout = () => {
  const navigation = useNavigate();

  const goBack = () => {
    // ๋’ค๋กœ๊ฐ€๊ธฐ
    navigation(-1); 
  };

  const goArticle = () => {
    // articles ๊ฒฝ๋กœ๋กœ ์ด๋™
    navigation("/articles", { replacetrue });
  };

  return (
    <div>
      <header style={{ background: "lightgreen", padding: 16, fontSize: 24 }}>
        <button onClick={goBack}>๋’ค๋กœ๊ฐ€๊ธฐ</button>
        <button onClick={goArticle}>๊ฒŒ์‹œ๊ธ€๋กœ ๊ฐ€๊ธฐ</button>
      </header>
      <main>
        <Outlet />
      </main>
    </div>
  );
};
export default Layout;

 

2. <NavLink> ์ปดํฌ๋„ŒํŠธ

: ๋งํฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ๋กœ๊ฐ€ ํ˜„์žฌ ๋ผ์šฐํŠธ์˜ ๊ฒฝ๋กœ์™€ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ ํŠน์ • ์Šคํƒ€์ผ or CSS ํด๋ž˜์Šค(className)๋ฅผ ์ ์šฉํ•œ๋‹ค.

์ด ์ปดํฌ๋„ŒํŠธ์˜ style๊ณผ className๋Š” { isActive? boolean } ์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋ฐ›๋Š” ํ•จ์ˆ˜ ํƒ€์ž…์˜ ๊ฐ’์„ ์ „๋‹ฌํ•œ๋‹ค.

Articles .js

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

const Articles = () => {

  const activeStyle = {
    color: "green",
    fontSize: "24px",
  };

  return (
    <div>
      <Outlet />
      <ul>
        <li>
          <NavLink
            to="/articles/1"
            style={({ isActive }) => (isActive ? activeStyle : undefined)}
          >
            ๊ฒŒ์‹œ๊ธ€1
          </NavLink>
        </li>

        <li>
          <NavLink
            to="/articles/2"
            style={({ isActive }) => (isActive ? activeStyle : undefined)}
          >
            ๊ฒŒ์‹œ๊ธ€2
          </NavLink>
        </li>

        <li>
          <NavLink
            to="/articles/3"
            style={({ isActive }) => (isActive ? activeStyle : undefined)}
          >
            ๊ฒŒ์‹œ๊ธ€3
          </NavLink>
        </li>
      </ul>
    </div>
  );
};
export default Articles;

 

3. NotFound ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

: ์ด ํŽ˜์ด์ง€๋Š” ์‚ฌ์ „์— ์ •์˜๋˜์ง€ ์•Š๋Š” ๊ฒฝ๋กœ์— ์‚ฌ์šฉ์ž๊ฐ€ ์ง„์ž…ํ–ˆ์„ ๋•Œ ๋ณด์—ฌ์ฃผ๋Š” ํŽ˜์ด์ง€

NotFound.js

const NotFound = () => {
  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        justifycontents: "center",
        fontSize: 64,
        position: "absolute",
        width: "100%",
        height: "100%",
      }}
    >
      404 error
    </div>
  );
};
export default NotFound;
App.js

import
{ Route, Routes } from "react-router-dom";
import "./App.css";
import Home from "./pages/Home";
import Layout from "./pages/Layout";
import NotFound from "./pages/NotFound";

function App() {
  return (
    <Routes>
      <Route element={<Layout />}>
        <Route index element={<Home />} />
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
}

export default App;

*๋Š” wildcard ๋ฌธ์ž๋กœ, ์•„๋ฌด ํ…์ŠคํŠธ๋‚˜ ๋งค์นญํ•œ๋‹ค๋Š” ๋œป

์ด ๋ผ์šฐํŠธ ์—˜๋ฆฌ๋จผํŠธ ์ƒ๋‹จ์— ์œ„์น˜ํ•˜๋Š” ๋ผ์šฐํŠธ๋“ค์˜ ๊ทœ์น™์„ ๋ชจ๋‘ ํ™•์ธํ•˜๊ณ , ์ผ์น˜ํ•˜๋Š” ๋ผ์šฐํŠธ๊ฐ€ ์—†๋‹ค๋ฉด ์ด ๋ผ์šฐํŠธ๊ฐ€ ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚จ.

 

4. <Navigate> ์ปดํฌ๋„ŒํŠธ

: ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™”๋ฉด์— ๋ณด์—ฌ์ฃผ๋Š” ์ˆœ๊ฐ„ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™. (์ฆ‰, ํŽ˜์ด์ง€๋ฅผ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.)

EX ) ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•œ ํŽ˜์ด์ง€์ธ๋ฐ ๋กœ๊ทธ์ธ์„ ์•ˆ ํ–ˆ๋‹ค๋ฉด, ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ธฐ

Login.js

const
Login = () => {
  return <div>๋กœ๊ทธ์ธ ํŽ˜์ด์ง€</div>;
};

export default Login;
App.js

import
{ Route, Routes } from "react-router-dom";
import "./App.css";
import Home from "./pages/Home";
import Layout from "./pages/Layout";
import Login from "./pages/Login";
import MyPage from "./pages/MyPage";
 

function App() {
  return (
    <Routes>
      <Route element={<Layout />}>
        <Route index element={<Home />} />
      <Route path="/login" element={<Login />} />
      <Route path="/mypage" element={<MyPage />} />
    </Routes>
  );
}

export default App;
MyPage.js

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

const MyPage = () => {
  const isLogin = false;

  if (!isLogin) {
    return <Navigate to="/login" replace={true} />;
  }
  return <div> ๋งˆ์ดํŽ˜์ด์ง€</div>;
};

export default MyPage;

๋ฆฌ์—‘ํŠธ ๋ผ์šฐํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ์†Œ ๊ฒฝ๋กœ์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ ์ฃผ๋Š” ๋ฐฉ๋ฒ•์„ ํ•™์Šตํ–ˆ์Šต๋‹ˆ๋‹ค.

์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ•  ์ปดํฌ๋„ŒํŠธ, ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ํ•˜๋Š” ๋กœ์ง, ๊ทธ ์™ธ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ํ•จ์ˆ˜๋“ค์ด ์ ์  ์Œ“์ด๋ฉด์„œ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์˜ ํฌ๊ธฐ๊ฐ€ ๋งค์šฐ ์ปค์ง‘๋‹ˆ๋‹ค.

์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ… (์ดํ›„์— ๋ฐฐ์šธ ๋‚ด์šฉ)

: ๋ผ์šฐํŠธ์— ๋”ฐ๋ผ ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋งŒ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋Š” ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ๋“ฑ ํ•„์š”ํ•œ ์‹œ์ ์— ๋ถˆ๋Ÿฌ์˜ค๋Š” ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•

 

 

728x90