React Router

Seulyi Yoo·2022년 7월 7일
0

React

목록 보기
8/12
post-thumbnail

React 의 라우팅 이해하기

(react-router-dom)


SPA 라우팅 과정

  1. 브라우저에서 최초에 ‘/’ 경로로 요청
  2. React Web App 을 내려줌
  3. 내려받은 React App 에서 ‘/’ 경로에 맞는 컴포넌트를 보여줌
  4. React App 에서 다른 페이지에 이동하는 동작을 수행
  5. 새로운 경로에 맞는 컴포넌트를 보여줌

npm i react-router-dom

  • cra 에 기본 내장된 패키지 아님
  • react-router-dom 은 facebook 의 공식 패키지 아님
  • 가장 대표적인 라우팅 패키지

npm create-react-app 파일명

npm i react-router-dom

특정 경로에서 보여줄 컴포넌트를 준비

  • ‘/’ ⇒ Home 컴포넌트
  • ‘/profile’ ⇒ Profile 컴포넌트
  • ‘/about’ ⇒ About 컴포넌트
// src/pages/Home.jsx

export default function Home(){
  return (
    <div>Home 페이지 입니다.</div>
  )
}
// src/pages/Profile.jsx

export default function Profile(){
  return (
    <div>Profile 페이지 입니다.</div>
  )
}
// src/pages/About.jsx

export default function About(){
  return (
    <div>About 페이지 입니다.</div>
  )
}
// App.js

import { BrowserRouter, Route } from 'react-router-dom';
import Home from './pages/Home';
import Profile from './pages/Profile';
import About from './pages/About';

function App() {
  return (
    <BrowserRouter>
      <Route path="/" exact component={Home} />
      <Route path="/Profile" component={Profile} />
      <Route path="/About" component={About} />
    </BrowserRouter>
  );
}

export default App;
```jsx
- Route 컴포넌트에 경로(path)와 컴포넌트(component) 를 설정하여 나열
- BrowserRouter 로 Route 들을 감싼다.
- Browser 에서 요청한 Route 의 path 가 들어있으면 해당 Component 를 보여줌

`<Route path="/" exact component={Home} />`   ⇒ 정확한 경로로 연결

## 이렇게 했지만 브라우저에 출력되지 않는 문제가 발생!!!!!!! 🤢
```jsx
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Home from './pages/Home';
import Profile from './pages/Profile';
import About from './pages/About';

function App() {
  return (
    
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/profile" element={<Profile />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </BrowserRouter>
    
  );
}

export default App;
  • <Routes></Routes> 로 감싸고
  • component={Home}element={<Home />} 로 변경
  • exact 옵션은 없어졌음. 만약 하위경로에 여러 라우팅을 매칭시키고 싶다면 url 뒤에 을 사용하여 일치시킬 수 있음 `<Route path="main/">`




Dynamic 라우팅(1)

url 를 동적으로 처리

/profile/1

// App.js

<Route path="/profile/:id" element={<Profile />} />
// src/pages/Profile.jsx

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

export default function Profile(props){
  // const id = props.match.params.id;
  const { id } = useParams();
  console.log(id, typeof id)
  return (
    <div>
      <h2>Profile 페이지입니다.</h2>
      {id && <p>id 는 {id} 입니다</p>}
      {/* id가 있을 경우에만 <p>태그 보임 */}
    </div>
  );
}

react 개정으로 const id = props.match.params.id; 를 쓰면 Error!!
usePrams(); 를 사용해야 함.
const { id } = useParams(); 로 변경해주었음!


Dynamic 라우팅(2)

/about?name=mark

// src/pages/About.jsx

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

export default function About(props){
  console.log(props);
  // const searchParams = props.location.search;
  const { search } = useLocation();
  console.log(search)
  return <div>About 페이지입니다.</div>;
}

react 개정으로 const searchParams = props.location.search; 를 쓰면 Error!!
useLocation(); 을 사용해야 함.
const { search } = useLocation(); 로 변경해주었음!

npm install query-string

// src/pages/About.jsx

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

export default function About(props){

  const { search } = useLocation();
  console.log(search)
  // const obj = new URLSearchParams(search); 
  // console.log(obj.get('name'))
  const query = queryString.parse(search);
  console.log(query);

  return (
    <div>
      <h2>About 페이지입니다.</h2>
      {query.name && <p>name은 {query.name} 입니다.</p>}
    </div>
  ); 
}



Switch 와 NotFound

v6 에서는 지원하지 않음

Switch ⇒ Routes

// 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';
import NotFound from './pages/NotFound';

function App() {
  return (
    
      <BrowserRouter>
        <Routes>
          <Route path="/profile/:id" element={<Profile />} />
          <Route path="/profile" element={<Profile />} />
          <Route path="/about" element={<About />} />
          <Route path="/" element={<Home />} />
          <Route path="/*" element={<NotFound />} />
        </Routes>
      </BrowserRouter>
    
  );
}

export default App;
// src/pages/NotFound.jsx

export default function NotFound(){
  return (
    <div>페이지를 찾을 수 없습니다.</div>
  )
}


JSX 링크로 라우팅 이동하기(1)

import { BrowserRouter, Route, Routes, Link } from 'react-router-dom';
import Home from './pages/Home';
import Profile from './pages/Profile';
import About from './pages/About';
import NotFound from './pages/NotFound';

function App() {
  return (
    
      <BrowserRouter>
        {/* <a href="/">Home</a> */}
        <Link to="/">Home</Link>
        <Routes>
          <Route path="/profile/:id" element={<Profile />} />
          <Route path="/profile" element={<Profile />} />
          <Route path="/about" element={<About />} />
          <Route path="/" element={<Home />} />
          <Route path="/*" element={<NotFound />} />
        </Routes>
      </BrowserRouter>
    
  );
}

export default App;

<a href="/">Home</a> 브라우저가 재실행되면서 페이지가 바뀜
<Link to="/">Home</Link> 브라우저 안에서 페이지 이동

// src/components/Links.jsx

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

export default function Links(){
  return (
    <ul>
      <li>
        <Link to="/">Home</Link>
      </li>
      <li>
        <Link to="/protile">Profile</Link>
      </li>
      <li>
        <Link to="/profile/1">Profile/1</Link>
      </li>
      <li>
        <Link to="/about">About</Link>
      </li>
      <li>
        <Link to="/about?name=mark">About?name=mark</Link>
      </li>
    </ul>
  );
}
// src/components/Links.jsx

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

export default function Links(){
  return (
    <ul>
      <li>
        <Link to="/">Home</Link>
      </li>
      <li>
        <Link to="/protile">Profile</Link>
      </li>
      <li>
        <Link to="/profile/1">Profile/1</Link>
      </li>
      <li>
        <Link to="/about">About</Link>
      </li>
      <li>
        <Link to="/about?name=mark">About?name=mark</Link>
      </li>
    </ul>
  );
}




JSX 링크로 라우팅 이동하기(2)

  • import { NavLink } from ‘react-router-dom’;
  • activeClassName, activeStyle 처럼 active 상태에 대한 스타일 지정이 가능함
    • ⇒ v6 에서 activeStyle, activeClassName 삭제되었음
  • Route 의 path 처럼 동작하기 때문에 exact 가 있음.
    • ⇒ v6 에서 exact 사용하지 않음
// 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';
import NotFound from './pages/NotFound';
import Links from './components/Links';
import NavLinks from './components/NavLinks';

function App() {
  return (
    
      <BrowserRouter>
        <Links />
        <NavLinks />
        <Routes>
          <Route path="/profile/:id" element={<Profile />} />
          <Route path="/profile" element={<Profile />} />
          <Route path="/about" element={<About />} />
          <Route path="/" element={<Home />} />
          <Route path="/*" element={<NotFound />} />
        </Routes>
      </BrowserRouter>
    
  );
}

export default App;
// src/components/NavLinks.jsx
import { NavLink } from "react-router-dom";

// const activeStyle = {color: "green"};
const ActiveColor = ({isActive}) => ({color: isActive? 'green':'black'})

export default function NavLinks(){
  
  return (
    <ul>
      <li>
        {/* <NavLink to="/" exact activeStyle={activeStyle}>Home</NavLink> */}
        <NavLink 
          to="/" 
          style={ActiveColor}>Home</NavLink>
      </li>
      <li>
        <NavLink 
          to="/profile"
          style={ActiveColor}>Profile</NavLink>
      </li>
      <li>
        <NavLink 
          to="/profile/1"
          style={ActiveColor}>Profile/1</NavLink>
      </li>
      <li>
        <NavLink 
          to="/about"
          style={ActiveColor}
          // isActive={(match, location) => {
          //   console.log(location);
          //   return match !== null && location.search === '';
          // }}
          >About</NavLink>
      </li>
      <li>
        <NavLink
          to="/about?name=mark"
          style={ActiveColor}
          // isActive={(match, location) => {
          //   return match !== null && location.search === "?name=mark"
          // }}
          >About?name=mark</NavLink>
      </li>
    </ul>
  );
}

react 개정으로 const activeStyle = {color: "green"};

<NavLink to="/" exact activeStyle={activeStyle}>Home</NavLink> 안 씀!
style={ActiveColor} 로 사용함!
isActive={(match, location) => { return match !== null && location.search === "?name=mark" }} 해결 안됨… 주소 겹치는 부분이 자꾸 같이 나와버림 🤢


JS 로 라우팅 이동하기

// v5
export default function Login(props){

  function login(){
      // 페이지로 이동
      setTimeout(()=>{
        props.history.push('/);
      },1000);
  }

  return(
    <div>
      <h2>Login 페이지입니다.</h2>
      <button onClick={login}>로그인하기</button>
    </div>
  );
}
// v6

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

export default function Login(){

  const navigate = useNavigate();    

  function login(){
      // 페이지로 이동
      setTimeout(()=>{
        navigate("/");
      },1000)
  }

  return(
    <div>
      <h2>Login 페이지입니다.</h2>
      <button onClick={login}>로그인하기</button>
    </div>
  );
}

react 개정으로 props.history.push('/); 사용하지 않음.
useNavigate() 를 사용하여 navigate(’경로’) 로 사용함.

profile
성장하는 개발자 유슬이 입니다!

0개의 댓글