본문 바로가기

공부/react

React 숙련 4 (react-router-dom)

반응형

react router dom 📖

리액트 프로젝트에서 라우팅을 가능하게 하는 라이브러리입니다.

 

설치 방법

yarn add react-router-dom

 

사용 방법

`About``Works``Home``Contact` 4개의 컴포넌트를 만듭니다.

컴포넌트 생성

 

가장 중요하다고 할 수 있는 부분인데요, 브라우저에서 URL을 입력하고 이동했을 때 원하는 페이지 컴포넌트로 이동하게 만드는 부분입니다.

import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "../pages/Home";
import About from "../pages/About";
import Contact from "../pages/Contact";
import Works from "../pages/Works";

const Router = () => {
  return (
    <BrowserRouter>
      <Routes>
      {/* 
        Routes안에 이렇게 작성합니다. 
        Route에는 react-router-dom에서 지원하는 props들이 있습니다.

        path는 우리가 흔히 말하는 사용하고싶은 "주소"를 넣어주면 됩니다.
        element는 해당 주소로 이동했을 때 보여주고자 하는 컴포넌트를 넣어줍니다.
      */}
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="contact" element={<Contact />} />
        <Route path="works" element={<Works />} />
      </Routes>
    </BrowserRouter>
  );
};

export default Router;

 

 

이후 App.jsx에 `Router.js`를 import 해줍니다.

import React from "react";
import Router from "./shared/Router";

function App() {
  return <Router />;
}

export default App;

 

`Router.js`를 App 컴포넌트에 넣어주는 이유는 가장 최상위 컴포넌트가 App.js이기 때문입니다. 그래서 path별로 분기가 되는 `Router.js`를 App.js에 위치시키고 App.js -> Router.js를 거치도록 구현해 주는 것입니다.

 

 

react-router-dom hooks 📖

react-router-dom에서도 hook을 제공합니다.

 

useNavigate

`navigate`를 생성하고 button을 클릭했을 때 우리가 보내고자 하는 path로 페이지를 이동시킬 수 있습니다.

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

const Home = () => {
  const navigate = useNavigate();

  return (
    <button
      onClick={() => {
        navigate("/works");
      }}
    >
      works로 이동
    </button>
  );
};

 

useLocation

현재 위치하고 있는 페이지의 여러 가지 정보를 얻을 수 있습니다.

// src/pages/works.js
import { useLocation } from "react-router-dom";

const Works = () => {
  const location = useLocation();
  console.log("location :>> ", location);
  return (
    <div>
      <div>{`현재 페이지 : ${location.pathname.slice(1)}`}</div>
    </div>
  );
};

export default Works;

location

 

Link

Link는 html 태그 중 a태그의 기능을 대체하는 API입니다. JSX에서 a태그를 이용해야 한다면 반드시 Link 태그를 사용해서 구현해야 합니다.

 

왜 a태그를 쓰면 안 될까

 

a태그를 사용해 페이지를 이동하면 새로고침 되기 때문입니다!

 

페이지를 이동하고자 할 때 `useNavigate` 또는 `Link`를 사용할 수 있습니다.

import { Link, useLocation } from 'react-router-dom';

const Works = () => {
  const location = useLocation();
  console.log('location :>> ', location);
  return (
    <div>
      <div>{`현재 페이지 : ${location.pathname.slice(1)}`}</div>
      <Link to="/contact">contact 페이지로 이동하기</Link>
    </div>
  );
};

export default Works;

 

 

children 📖

어떤 엘리먼트가 들어올지 미리 예상할 수 없는 경우 `범용적인 박스` 역할을 하는 컴포넌트란 크게 봤을 때 Layout 역할을 하는 컴포넌트라고 생각해 볼 수 있습니다.

 

예시 코드

// src/shared/Layout.js

import React from 'react';

const HeaderStyles = {
  width: '100%',
  background: 'black',
  height: '50px',
  display: 'flex',
  alignItems: 'center',
  paddingLeft: '20px',
  color: 'white',
  fontWeight: '600',
};
const FooterStyles = {
  width: '100%',
  height: '50px',
  display: 'flex',
  background: 'black',
  color: 'white',
  alignItems: 'center',
  justifyContent: 'center',
  fontSize: '12px',
};

const layoutStyles = {
  display: 'flex',
	flexDirection: 'column',
  justifyContent: 'center',
  alignItems: 'center',
  minHeight: '90vh',
}

function Header() {
  return (
    <div style={{ ...HeaderStyles }}>
      <span>Sparta Coding Club - Let's learn React</span>
    </div>
  );
}

function Footer() {
  return (
    <div style={{ ...FooterStyles }}>
      <span>copyright @SCC</span>
    </div>
  );
}


function Layout({ children }) {
  return (
    <div>
      <Header />
      <div style={{...layoutStyles}}>
        {children}
      </div>
      <Footer />
    </div>
  );
}

export default Layout;

 

import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Home from '../pages/Home';
import About from '../pages/About';
import Contact from '../pages/Contact';
import Works from '../pages/Works';
import Layout from './Layout';

const Router = () => {
  return (
    <BrowserRouter>
      <Layout>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="about" element={<About />} />
          <Route path="contact" element={<Contact />} />
          <Route path="works" element={<Works />} />
        </Routes>
      </Layout>
    </BrowserRouter>
  );
};

export default Router;

 

`Layout` 컴포넌트는 children을 props를 받고 Router에 공통 레이아웃을 담당하고 있습니다.

 

Dynamic Route📖

path에 유동적인 값을 넣어서 특정 페이지로 이동하게끔 구현하는 방법입니다.

 

사용 방법

 <Route path="works/:id" element={<Works />} />

 

`works/:id`라고 path가 들어갑니다. `:id`는 동적인 값을 받겠다는 뜻입니다.

 

 

아래 예시 코드처럼 Link 태그를 클릭하게 되면 `works/${work.id}`경로로 이동하게 됩니다.

// Works.jsx
function Works() {
  return (
    <div>
      {data.map((work) => {
        return (
          <div key={work.id}>
            <div>할일: {work.id}</div>
            <Link to={`/works/${work.id}`}>
              <span>➡️ Go to: {work.todo}</span>
            </Link>
          </div>
        );
      })}
    </div>
  );
}

 

 

`useParams()`를 사용해 react-router-dom에서 동적 라우팅을 값을 받아와 사용할 수 있습니다.

const param = useParams();
console.log(param) // { id: '6' }

 

 

중첩 라우트 (Outlet)📖

특정 라우트 내에서 추가적인 라우트를 정의하는 방식입니다. 여러 계층의 UI를 구성할 때 유용하게 사용됩니다.

 

import { BrowserRouter, Routes, Route } from 'react-router-dom';
import DashboardLayout from './DashboardLayout';
import Profile from './Profile';
import Settings from './Settings';
import Reports from './Reports';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/dashboard" element={<DashboardLayout />}>
          <Route index element={<Profile />} />
          <Route path="settings" element={<Settings />} />
          <Route path="reports" element={<Reports />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

 

위 코드에서 `<DashboardLayout />` 컴포넌트를 사용하고 이 레이아웃 내에서 `/dashboard/settings` `/dashboard/reports`등의 경로로 추가적인 페이지들을 중첩해 설정할 수 있습니다.

 

Outlet

`Outlet` 컴포넌트는 중첩 라우팅 환경에서 부모 라우트 내에 렌더링 되어야 할 자식 라우트를 표시할 위치를 정의합니다.

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

function DashboardLayout() {
  return (
    <div>
      <h1>대쉬보드!</h1>
      <Outlet />  {/* 여기에 자식 라우트의 컴포넌트가 렌더링됩니다. */}
    </div>
  );
}

 

 

`<Outlet />` 부분이 아래 컴포넌트로 대체가 돼서 보이는 것입니다.

<Route path="settings" element={<Settings />} />
<Route path="reports" element={<Reports />} />

 

 

중첩 라우팅 vs 공통 레이아웃

중첩 라우팅을 사용하면 각 라우트마다 고유의 Layout을 적용할 수 있습니다.

 

<Routes>
  <Route path="/" element={<Layout />}>
    <Route index element={<Home />} />
    <Route path="about" element={<About />} />
  </Route>
</Routes>

 

 

공통 Layout을 사용하는 방식은 모든 라우트에 동일한 레이아웃을 적용하고 싶을 때 유용합니다.

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

 

반응형