React Router

SPA (Single Page Application)

ํŽ˜์ด์ง€๊ฐ€ ํ•œ ๊ฐœ์ธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜.

  • react๋Š” ํ•˜๋‚˜์˜ htmlํŒŒ์ผ์— ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„๋จ
  • ํ•˜๋‚˜์˜ htmlํŒŒ์ผ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด Routing


โ—‹ Routing

๋‹ค๋ฅธ ๊ฒฝ๋กœ(url ์ฃผ์†Œ)์— ๋”ฐ๋ผ ๋‹ค๋ฅธ View(ํ™”๋ฉด)์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ

  • react ์ž์ฒด์—๋Š” ์ด๋Ÿฐ ๊ธฐ๋Šฅ์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์ง€ ์•Š์•„ ๋ณ„๋„๋กœ ์„ค์น˜ํ•ด์•ผ ํ•œ๋‹ค
    • react๊ฐ€ framework๊ฐ€ ์•„๋‹Œ library๋กœ ๋ถ„๋ฅ˜๋˜๋Š” ์ด์œ 
    • React-router react์˜ routing ๊ธฐ๋Šฅ์„ ์œ„ํ•ด ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” library


โ— React-router

๐Ÿ”˜ react-router ์„ค์น˜

  • โ€˜npm install react-router-dom โ€“saveโ€™
    • --save package.jsonํŒŒ์ผ์˜ dependencies์— ์ถ”๊ฐ€๋˜๋„๋ก ํ•˜๋Š” ๋ช…๋ น์–ด


๐Ÿ”˜ Routes component ๊ตฌํ˜„

  • Routes.js๋ฅผ ๋งŒ๋“ค์–ด์„œ ์—ฐ๊ฒฐํ•ด์•ผ ํ•˜๋Š” component๋ฅผ <Router> ์•„๋ž˜์— ์œ„์น˜์‹œํ‚ค๊ธฐ
    • <Router> ์•„๋ž˜์— ์œ„์น˜ ์‹œํ‚จ๋‹ค๋Š” ๋ง์€, <Router>๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ฒ ๋‹ค๋ผ๋Š” ๋œป
import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

// import Component๋ช… from 'file ๊ฒฝ๋กœ';
import Login from "./pages/Login/Login";
import Signup from "./pages/Signup/Signup";
import Main from "./pages/Main/Main";

class Routes extends React.Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route exact path='/' component={Login} />
          <Route exact path='/signup' component={Signup} />
          <Route exact path='/main' component={Main} />
        </Switch>
      </Router>
    );
  }
}

export default Routes;


๐Ÿ”˜ index.js

ReactDOM.render(<Routes />, document.getElementById('root'));


๐Ÿ”˜ Route ์ด๋™

  • <Link> ํ”„๋กœ์ ํŠธ ํŒŒ์ผ ๋‚ด, ์กฐ๊ฑด์—†์ด ์ด๋™ํ•  ๋•Œ ์‚ฌ์šฉ
    • <Link to="/signup">ํšŒ์›๊ฐ€์ž…</Link>
  • withRouterHOC ์กฐ๊ฑด์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์‚ฌ์šฉ
import React from "react";
import { withRouter } from "react-router-dom";

class Login extends React.Component {
  goToMain = () => {
    this.props.history.push("/main");
  };

  render() {
    return (
      <div>
        <button className='loginBtn' onClick={this.goToMain}>
          ๋กœ๊ทธ์ธ
        </button>
      </div>
    );
  }
}

export default withRouter(Login);



โœจ react-router-dom v6 ๋ณ€๊ฒฝ์‚ฌํ•ญ

์–ด๋Š ์ˆœ๊ฐ„๋ถ€ํ„ฐ Switch๋ฅผ react-router-dom ํŒจํ‚ค์ง€์—์„œ import ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ์ƒ๊ฒผ๋Š”๋ฐ, ์•Œ๊ณ  ๋ณด๋‹ˆ react-router-dom v6์—์„œ Switch๊ฐ€ Routes๋กœ ๋ฐ”๋€Œ์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค.


โœ”๏ธ Switch โžก๏ธ Routes๋กœ ๋ณ€๊ฒฝ๋จ

// v5
<Switch>
  <Route ... />
</Routes>

// v6
<Routes>
  <Route ... />
</Routes>


โœ”๏ธ exact ์˜ต์…˜ ์‚ญ์ œ

  • path ๋ฅผ ๊ธฐ์กด์˜ path="/Web/:id" ์—์„œ path=":id" ๋กœ, ์ƒ๋Œ€๊ฒฝ๋กœ๋กœ ์ง€์ •
  • ์ด ์™ธ์—๋„, path=".", path=".." ๋“ฑ์œผ๋กœ ์ƒ๋Œ€๊ฒฝ๋กœ๋ฅผ ํ‘œํ˜„
// categores ๋กœ ์‹œ์ž‘๋˜๋Š” ๋ชจ๋“  ๋ผ์šฐํŒ… ๋งค์นญ
<Route path='categories/*' />


โœ”๏ธ route ์—์„œ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง

// v5 ๋ฒ„์ „ ์‚ฌ์šฉ ์˜ˆ์‹œ
<Route exact path="/" component={Login} />
  )}
/>

// v6 ๋ฒ„์ „ ์‚ฌ์šฉ ์˜ˆ์‹œ
<Route path="/" component={<Login />} />


โœ”๏ธ useHistory โžก๏ธ useNavigate hook ๋ณ€๊ฒฝ

// v5
const history = useHistory();

history.push('/home');
history.replace('/home');

// v6
const navigate = useNavigate();

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

// v6 ์—์„œ์˜ ์•ž์œผ๋กœ, ๋’ค๋กœ ๊ฐ€๊ธฐ ์‚ฌ์šฉ๋ฐฉ๋ฒ• ๋ณ€ํ™”
<button onClick={() => navigate(-2)}>Go 2 pages back</button>
<button onClick={() => navigate(-1)}>Go back</button>
<button onClick={() => navigate(1)}>Go forward</button>
<button onClick={() => navigate(2)}>Go 2 pages forward</button>


โœ”๏ธ v6 ์ค‘์ฒฉ ๋ผ์šฐํŒ…

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

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path='/' element={<Home />} />
        <Route path='users' element={<Users />}>
          <Route path='me' element={<OwnUserProfile />} />
          <Route path=':id' element={<UserProfile />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

function Users() {
  return (
    <div>
      <nav>
        <Link to='me'>My Profile</Link>
      </nav>

      <Outlet />
    </div>
  );
}


โœ”๏ธ ์ฝ”๋“œ๋กœ ํ™•์ธํ•˜๊ธฐ

import React from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Login from "./pages/Login/Login";
import Signup from "./pages/Signup/Signup";
import Main from "./pages/Main/Main";

class Routes extends React.Component {
  render() {
    return (
      <Router>
        <Routes>
          <Route path='/' component={<Login />} />
          <Route path='/signup' component={<Signup />} />
          <Route path='/main' component={<Main />} />
        </Routes>
      </Router>
    );
  }
}



โœ… ๋ชฉํ‘œ!

  • SPA์˜ ๊ฐœ๋…์— ๋Œ€ํ•ด ์ดํ•ดํ•˜๊ณ 
  • router๊ฐ€ ๋ฌด์—‡์ด๊ณ  ์™œ ์จ์•ผ ํ•˜๋Š”์ง€,
  • router ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ตํžˆ์ž