Front-End/React

[React] 리액트 라우터(react-router-dom) v6 사용법

LightSource 2022. 8. 29. 21:08

프로젝트에 라우터 적용

  • $ yarn add react-router-dom 명령어 실행하여 라이브러리 설치

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById('root')
);
  • BrowserRouter라는 컴포넌트를 이용하여 App를 감싸면 라우터가 적용이 된다.

<Route>로 특정 주소에 컴포넌트 연결

  • Route 컴포넌트를 사용하면 어떤 규칙을 가진 경로에 어떤 컴포넌트를 보여줄지 정의할 수 있다.

사용 방법

<Routes>
    <Route path="주소규칙" component={보여 줄 컴포넌트}/>
    <Route path="주소규칙" component={보여 줄 컴포넌트}/>
</Routes>

예시

const App = () => {
  return (
      <div>
          <Routes>
        <Route path="/" element={<Home/> } />            // localhost:3000/ 접속시 Home 컴포넌트 출력
        <Route path='/about' element={<About/> } />      // localhost:3000/about 접속시 About 컴포넌트 출력
          </Routes>
      </div>
  );
}

export default App;

<Link>컴포넌트 사용하여 다른 주소로 이동

  • 클릭하면 다른 주소로 이동시켜주는 컴포넌트이다.
  • <a>와 용도가 같으나 는 리액트에서는 사용하면 안된다 → 페이지를 새로 불러오기 때문에 애플리케이션이 들고 있던 상태들이 다 날라감

사용 방법

<Link to="주소">내용</Link>

예시

const App = () => {
  return (
      <div>
          <ul>
              <li>
                  <Link to="/">홈</Link>
              </li>
              <li>
                  <Link to="/about">소개</Link>
              </li>
          </ul>
            <hr/>
          <Routes>
        <Route path="/" element={<Home/> } />
        <Route path='/about' element={<About/> } />
          </Routes>
      </div>
  );
}

export default App;

URL Params 사용

  • 파라미터 예시 : /profiles/lightsource
  • 주소 뒷부분에 유동적인 username 값을 넣어 줄 때 해당 값을 props로 받아와서 조회한다.
  • useParams 객체를 사용하면 된다.

사용 방법

//props로 넘겨받는 컴포넌트
import { useParams } from 'react-router-dom';

const Profile = () => {
    const {param이름} = useParams();
}

//props를 주는 컴포넌트
<Route path="/profiles/param이름" element={<Profile />} />

예시

Profile.js

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

const data = {
    lightsource: {
        name: 'lightsourcecoder',
        description : '리액트를 공부하는 중인 개발자 꿈나무'
    },
    gildong: {
        name: '홍길동',
        description: '고전 소설 홍길동전의 주인공'
    }
}

const Profile = () => {
    const {username} = useParams();   //useParams()에서 파라미터를 받음
    const profile = data[username];   //data에서 해당 하는 값을 가져온다.
    if(!profile) {
        return <div>존재하지 않는 사용자입니다.</div>;
    }
    return (
        <div>
            <h3>
                {username}({profile.name})
            </h3>
            <p>{profile.description}</p>
        </div>
    );
};

export default Profile;

App.js

import React from 'react';
import {Link, Route, Routes} from 'react-router-dom';
import About from './About';
import Home from './Home';
import Profile from "./Profile";

const App = () => {
  return (
      <div>
          <ul>
              <li>
                  <Link to="/">홈</Link>
              </li>
              <li>
                  <Link to="/about">소개</Link>
              </li>
              <li>
                  <Link to="/profile/lightsource">lightsource 프로필</Link>
              </li>
              <li>
                  <Link to="/profile/gildong">gildong 프로필</Link>
              </li>
          </ul>
            <hr/>
          <Routes>
        <Route path="/" element={<Home/> } />
        <Route path='/about' element={<About/> } />
        <Route path='/info' element={<About/> } />
        // path 규칙에 :username을 추가하여 username param값을 가져온다. 
        <Route path="/profile/:username" element={<Profile/> } /> 
          </Routes>
      </div>
  );
}

export default App;

URL 쿼리

  • 쿼리 예시 : /about?details=true
  • useLocation 객체를 사용해서 값을 가져온다.

사용 예시

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

const About = () => {
    const {search} = useLocation();
    const detail = search === '?detail=true'; //현재 경로가(search) '?detail=true' 인지 확인
    return (
        <div>
            <h1>소개</h1>
            <p>이 프로젝트는 리액트 라우터 기초를 실습해 보는 예제 프로젝트입니다.</p>
            {detail && <p>detail값을 true로 설정하셧군요!</p>}
        </div>
    );
};

export default About;

서브 라우트(중첩 라우팅)

  • 라우트 내부에 또 라우트를 정의하는 것을 의미한다.

사용 방법

// Profiles 컴포넌트에 있는 Route 
return (
  <Routes>          // Routes로 감싸줘야함!!!
            <Route path="/*" element={<div>사용자를 선택해 주세요.</div>} />  // profiles 이하의 모든 주소를 설정
      <Route path=":username" element={<Profile />} /> 
  </Routes>
);

// App.js
const App = () => {
  return (
            <Routes>
          <Route path="/" element={<Home/>}/>
          <Route path='/about' element={<About/>}/>
          <Route path='/info' element={<About/>}/>
          <Route path="/profiles/*" element={<Profiles/>}/>
      </Routes>
        </div>
  );
};
  • 하위 페이지가 있다면 부모 Route에 ‘/*’ 을 추가해준다.
  • path에 부모 경로까지 적을 필요 없이 파라미터만 적어줘도 된다 (path=":username")

useNavigate 사용

  • v5의 history 기능을 담당
  • useNavigate는 리액트의 부가기능을 제공해준다.
  • 특정버튼을 눌렀을때 뒤로 가기, 로그인 후 화면 전환, 다른페이지로 이탈하는것을 방지 등
function UseNavigateSample() {
    const navigate = useNavigate();

    // 뒤로가기
    const goBack = () => {
        navigate(-1);
    }

    // 홈으로 가기
    const goHome = () => {
        navigate('/');
    }

        return (
            <div>
                <button onClick={goBack}>뒤로</button>
                <button onClick={goHome}>홈으로</button>
            </div>
        );
}

export default UseNavigateSample;

라우트 컴포넌트가 아닌곳에서 라우트 객체 접근 방법

  • v5의 withRouter를 대체하는 방법
  • 라우트로 사용된 컴포넌트가 아니어도 useParams, useLocation, useNavigate 객체 접근방법
const WithRouterInstead = () => {
    let params = useParams();      // URL 파라미터
    let location = useLocation();  // URL 쿼리 
    let navigate = useNavigate();  // 부가기능(앞으로가기, 뒤로가기, 홈으로 등)
    return (
        <div>
            <h4>Location</h4>
            <textarea value={JSON.stringify(location, null, 2)} readOnly />

            <h4>Params</h4>
            <textarea value={JSON.stringify(params)} readOnly />

            <button onClick={() => navigate('/')}>홈으로</button>
        </div>
    );
};

export default WithRouterInstead;

존재하지 않는 페이지 설정

  • Route의 경로를 /* 로 설정시 정의하지 않은 모든 주소에 설정된다.
<Routes>
        <Route path="/*" element={<h1>존재하지 않는 페이지 입니다</h1>}/>
</Routes>

<NavLink>로 특정 주소에 스타일, css 적용

  • style 속성은 스타일을 적용
  • className값은 CSS클래스를 적용한다.
<NavLink
        to="/profiles/lightsource"
        style={({ isActive }) => ({
                color: isActive ? 'white' : '',
                background : isActive ? 'black':'white'
        })}
>lightsource</NavLink>

참고

https://kyung-a.tistory.com/36

리액트를 다루는 기술 - 김민준

반응형