๊ฐœ๋ฐœ ๐Ÿพ/ReactJS

[React][ํ™˜๊ฒฝ์„ธํŒ…] react-router-dom ์‚ฌ์šฉํ•˜๊ธฐ

JOTOKKI 2021. 5. 25. 15:11
728x90

React ๊ฐœ๋ฐœ ์‹œ ๊ท€์ฐฎ์€ ํ™˜๊ฒฝ ์„ธํŒ…์„ ๊ธฐ์–ต์ด ๋‚˜์ง€ ์•Š์„ ๋•Œ ์ผ์ผ์ด ์ฐพ์•„ ์‚ฌ์šฉํ•˜๊ธฐ ๋ฒˆ๊ฑฐ๋กญ๊ธฐ ๋•Œ๋ฌธ์— ๋ฏธ๋ฆฌ ์ •๋ฆฌํ•ด ๋†“๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค. 

 

์ฐธ์กฐ 1: https://reactrouter.com/web/guides/quick-start

์ฐธ์กฐ 2: ๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ  ์„œ์  - ๋ฒจ๋กœ ํผํŠธ 

๊ฐœ์š”

SPA์˜ ๋‹จ์ ์ค‘ ํ•˜๋‚˜๋Š” ๋„ˆ๋ฌด ๋งŽ์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ•œ ๋ฒˆ์— ๋ถˆ๋Ÿฌ์˜จ๋‹ค๋Š” ๊ฒƒ์ธ๋ฐ,

์ด ๋ฌธ์ œ๋Š” ์ฝ”๋“œ์Šคํ”Œ๋ฆฟ์„ ํ†ตํ•ด ํ•ด์†Œํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๋ผ์šฐํŠธ ๋ณ„๋กœ ํŒŒ์ผ๋“ค์„ ๋‚˜๋ˆ„์–ด ํŠธ๋ž˜ํ”ฝ๊ณผ ๋กœ๋”ฉ ์†๋„๋ฅผ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด ์ง€์ง€๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ์‚ฌ์ดํŠธ๋Š” ๊ฑฐ์˜ ํ•„์ˆ˜๋กœ ์ ์šฉ๋œ๋‹ค๊ณ  ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

 

์„ค์น˜

yarn add react-router-dom 

 

์„ค๋ช…

  • BrowserRouter: ์ฃผ์†Œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ props์— ๋‹ด์•„ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • : HTML5์˜ History API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ๊ณ ์นจ ํ•˜์ง€ ์•Š๊ณ  ์ฃผ์†Œ๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.
  • Link: history API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๊ทธ๋Œ€๋กœ ๋‘๊ณ  ๊ฒฝ๋กœ๋งŒ ๋ณ€๊ฒฝํ•œ๋‹ค.
  • : a ํƒœ๊ทธ๋Š” ํŽ˜์ด์ง€๋Š” ์ „ํ™˜ํ•˜๋Š” ๊ณผ์ •์—์„œ ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ด์œผ๋กœ Link๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • URL Paramter || Query Parameter
    • URL Parameter
    • : /user/info
    • Query Paramter
    • : /user?detail=info

 

๋น ๋ฅด๊ฒŒ ์„ธํŒ…ํ•˜๊ธฐ

1. ๋ผ์šฐํ„ฐ๊ฐ€ ํ•„์š”ํ•œ ์˜์—ญ ์ „์ฒด๋ฅผ BrowserRouter๋กœ ๊ฐ์‹ธ์ฃผ๊ธฐ

: ๊ผญ index.js ์•ˆ์— ๊ฐ์‹ธ์ค„ ํ•„์š”๋Š” ์—†์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์ดํŠธ๋Š” ์ „์—ญ์„ ์ƒ๋Œ€๋กœ ํ™”๋ฉด ์ „ํ™˜์„ ํ•˜๋ฏ€๋กœ index.js๋‚˜ App.js, ํ˜น์€ ๋ฉ”์ธ์ด ๋˜๋Š” ํŽ˜์ด์ง€์—์„œ ๊ฐ์‹ธ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์•ผ ์ „๋‹ฌ๋˜๋Š” props๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด ์ œ๋Œ€๋กœ ์ž‘๋™์ด ๋ฉ๋‹ˆ๋‹ค. 

// index.js
import { BrowserRouter } from 'react-router-dom';

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

 

2. ๋งํฌ ๋งŒ๋“ค์–ด์ฃผ๊ธฐ (๋‚ด๋น„๊ฒŒ์ด์…˜)

๋ฆฌ์•กํŠธ๋Š” ํŽ˜์ด์ง€ ์ด๋™์„ ์œ„ํ•ด a ํƒœ๊ทธ ๋Œ€์‹  Link๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. 

a ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ํŽ˜์ด์ง€ ์ƒˆ๋กœ๊ณ ์นจ์ด ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— SPA ๊ฐœ๋ฐœ ํŠน์„ฑ์ƒ ์ „์ฒด ์ƒˆ๋กœ๊ณ ์นจ์ด ์•„๋‹Œ ๋ถ€๋ถ„ ๋ Œ๋”๋ฅผ ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— a ํƒœ๊ทธ ๋Œ€์‹  Link ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. 

๋ Œ๋” ์ดํ›„์— ๊ฐœ๋ฐœ์ž ๋ชจ๋“œ์—์„œ๋Š” a ํƒœ๊ทธ๋กœ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋ฉด css ๋˜ํ•œ a ํƒœ๊ทธ๋กœ ์ƒ๊ฐํ•˜๊ณ  ์Šคํƒ€์ผ์„ ์ž…ํžˆ๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

// Nav.js
import React from 'react'
import { Link } from 'react-router-dom'

function Nav() {
    return (
        <ul className="navList">
            <li className="navItem"><Link to="/">Home</Link></li>
            <li className="navItem"><Link to="/info">Info</Link></li>
            <li className="navItem"><Link to="/user">User</Link></li>
        </ul>
    )
}

export default Nav

 

3. ๋งํฌ ๋ณ„ ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

ํŠน์ • url ์ด์™ธ์— ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ์ ‘์†ํ–ˆ์„ ๊ฒฝ์šฐ ๋ฌด์กฐ๊ฑด 404 ํŽ˜์ด์ง€๋ฅผ ๋„์šฐ๊ณ  ์‹ถ๋‹ค๋ฉด 

๋งˆ์ง€๋ง‰์— NotFound ํŽ˜์ด์ง€๋ฅผ Route์— ๊ฑธ์–ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

// App.js
import {
  Switch,
  Route
} from 'react-router-dom'

//components
import Nav from './components/Nav'
import { 
  Home,
  Info,
  User,
  NotFound
} from './pages'

function App() {
  return (
    <div className="App">
      <Nav/>
      <hr/>
      <Switch>
        <Route exact path="/" component={Home}/>
        <Route exact path="/user" component={User}/>
        <Route exact path="/info" component={Info}/>
        <Route component={NotFound} />  // url์ด /, /user, /info์•„ ์•„๋‹Œ ๋ชจ๋“  ๊ฒฝ์šฐ NotFound๊ฐ€ ๋ Œ๋”๋ฉ๋‹ˆ๋‹ค
      </Switch> 
    </div>
  );
}
export default App;

 

4-1. URL Paramter ์‚ฌ์šฉํ•˜๊ธฐ

user๋ผ๋Š” ํŽ˜์ด์ง€์— userid๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๊ฐ’์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. 

๋งŒ์•ฝ url์— '/user/hong'์ด๋ผ๊ณ  ์ ‘์†์„ ํ•˜๋ฉด, ์ปดํฌ๋„ŒํŠธ ํŽ˜์ด์ง€์—์„œ๋Š” userid='hong'์œผ๋กœ ๋‹ด๊ฒจ์˜ต๋‹ˆ๋‹ค.

 

// - App.js
- App.js
<Switch>
	{...}
	<Route exact path={["/user/:userid", "/user"]} component={User}/>
</Switch>

์ € ๊ฐ’(๋„˜์–ด์˜ค๋Š” userid์˜ value๊ฐ’)์— ์ ‘๊ทผ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ

match.params. ํ‚ค๊ฐ’  (์—ฌ๊ธฐ์„œ ํ‚ค๊ฐ’์€ userid๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.)์œผ๋กœ ์ ‘๊ทผํ•˜์—ฌ ๊ฐ’์„ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.  

- User.js

// ๋ชฉ์—…๋ฐ์ดํ„ฐ
const data = {
    user1: {
        name: 'ํ™๊ธธ๋™',
        userId: 'hong'
    },
    user2: {
        name: '๊น€๋‘˜๋ฆฌ',
        userId: 'kim'
    }
}
const User = ({ match }) => {
    const userid = match.params.userid; // match.params๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ
    const userId2 = data[userid];  // ์œ„ data๋ชฉ์—…๋ฐ์ดํ„ฐ ์—์„œ ํ‚ค๊ฐ’์„ ์ฐพ์•„ ์กด์žฌ์—ฌ๋ถ€ ํ™•์ธ    
    return (
        <div>
            This is User Page! <br/>
            {
                userId2 ?
                <p>User id is {userid}</p> : 
                <p>No User</p>
            }
        </div>
    )
}
export default User

 

 

4-2. Query Paramter ์‚ฌ์šฉํ•˜๊ธฐ

url parameter์—์„œ๋Š” url/:key ์ด๋ ‡๊ฒŒ ๊ฐ’์„ ์ „๋‹ฌํ–ˆ๋‹ค๋ฉด,

query parameter์—์„œ๋Š” /url? key=value ์ด๋ ‡๊ฒŒ ๊ธฐ์กด get ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. (์ €๋Š” ์ง€๊ธˆ๋„ ๋ช…์นญ์ด ๋„ˆ๋ฌด ํ–ˆ๊ฐˆ๋ฆฝ๋‹ˆ๋‹ค ^^;;)

- App.js

<Route exact path={["/info?userid='user1'", "/info"]} component={Info}/>

๋Œ€์‹  ๊ฐ’์„ ๋ฐ›์•„๋ณด๊ธฐ ์œ„ํ•ด url๋’ค์— ๋ถ™์€? ๊ฐ’์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ํ•œ ๋ฒˆ ๋” ์ž‘์—…์„ ํ•ด์ฃผ๋ฉด ๊น”๋”ํ•˜๊ฒŒ ๊ฐ’์„ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

์ €๋Š” '๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ '์ด๋ผ๋Š” ์ฑ…์„ ๋ณด๊ณ  ํ•™์Šต์„ ํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ์„œ์ ์—์„œ ์ œ์‹œํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ qs๋ฅผ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค. 

 

* qs ์„ค์น˜ 

: qs๋Š” querystring ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ด๋ฆฌ์ €๋ฆฌ(?) ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. 

yarn add qs

query parameter์˜ ๊ฐ’์€ location์—์„œ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

- Info.js

import qs from 'qs'
// ๋ชฉ์—…๋ฐ์ดํ„ฐ
const data = {
    user1: {
        name: 'ํ™๊ธธ๋™',
        detail: 'hong gill dong detail'
    },
    user2: {
        name: '๊น€๋‘˜๋ฆฌ',
        detail: 'kim dool li detail'
    }
}
const Info = ({ location }) => {
	// location ์—์„œ ๋ฐ›์Œ
    const query = qs.parse(location.search, {
        ignoreQueryPrefix: true // url ์ƒ์— ์•ž์— ? ๋ฅผ ignoreํ•จ 
    })
    const queryCheck = data[query.userid];
    return (
        <div>
            This is info Page! <br/>
            {
                queryCheck &&
                <p>{queryCheck.userid}</p>
            }
        </div>
    )
}
export default Info

 

์ด๋ ‡๊ฒŒ ์ •๋ฆฌํ•ด ๋‘๋‹ˆ ๊ดœํžˆ ๋ฟŒ๋“ฏํ•ฉ๋‹ˆ๋‹ค. โœจ

๋ฐ˜์‘ํ˜•