TIL #22 | Router React Dom

kibi·2023년 11월 9일
1

TIL (Today I Learned)

목록 보기
21/83

React Router Dom

여러 페이지를 이동할 수 있도록 화면 전환을 돕는 리액트 패키지


패키지 설치 : yarn add react-router-dom

구현 순서
(1) 페이지 컴포넌트 생성
(2) Router.js 생성 및 router 설정 코드
(3) App.js에 Router import 및 적용

파일 구성

  • Pages : 각각의 페이지 컴포넌트를 구성한다.
  • shared : 공통으로 쓸 사용할 코드 작성
    - Router.js : 라우터 컴포넌트 및 경로 지정
    • Layout.js : 공통으로 사용할 레이아웃 구현
    • data.js : 데이터 저장


Router.js

  • BrowswerRouter
  • Routes
  • Route
    - path에 이동할 경로를 지정하고, element에 페이지 컴포넌트를 지정해준다.
    - :id 와 같이 설정하여 parameters를 넘겨줄 수 있다
    -> Dynamic Route 구현
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 Work from "../pages/Work";

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

export default Router;

App.jsx에 import 하여 사용한다.

import "./App.css";
import Router from "./shared/Router";

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


react-router-dom Hooks

useNavigate

이벤트가 발생할 시 다른 페이지로 이동시키기 위해 사용한다.

  • import useNavigate
  • navigate에 변수를 지정하여 사용한다.
  • ex) navigate("/works")
import React from "react";
import { useNavigate } from "react-router-dom";

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

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

export default Home;

useLocation

  • 현재 위치한 페이지의 여러가지 정보를 추가적으로 얻을 수 있게 한다.
    - pathname과 같은 데이터를 가져올 수 있다.
import React from "react";
import { useNavigate,  } from "react-router-dom";

function Works() {
  const location = useLocation();
  return (
    <div>
	    <p>{location.pathname}</p>
    </div>
  );
}

export default Works;

HTML의 a 태그 기능을 대체하는 API이다.

a 태그가 아닌 Link를 사용하는 이유?
-> a 태그를 사용하면 페이지를 이동하면서 브라우저가 새로고침 되기 때문에 불필요한 렌더링이 일어날 수 있기 때문!

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

function Works() {
  
  return (
    <div>
      <Link to="/contact">contact 페이지로 이동하기</Link>
    </div>
  );
}

export default Works;

children

children props 특성을 사용하여 개별적으로 존재하는 Header, Footer, Page를 합성하여 UI를 구현할 수 있다.

// 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',
}

// Header 컴포넌트
function Header() {
  return (
    <div style={{ ...HeaderStyles }}>
      <span>Header</span>
    </div>
  );
}

// Footer 컴포넌트
function Footer() {
  return (
    <div style={{ ...FooterStyles }}>
      <span>Footer</span>
    </div>
  );
}

// Header, Footer와 children 값을 받아 UI를 구현하는 Layout 컴포넌트
function Layout({ children }) {
  return (
    <div>
      <Header />
      <div style={{...layoutStyles}}>
        {children}
      </div>
      <Footer />
    </div>
  );
}

export default Layout;
  • Router.js에 import 하여 UI 구현 시 Header와 Footer 사이에 존재할 컴포넌트를 감싸준다.
  • 페이지는 이동하지만 기본적인 UI(헤더, 푸터, 메뉴)는 유지하고 싶을 때 사용할 수 있다.
// shared/Router.js

// Layout import
import Layout from "./Layout";

// Layout으로 children으로 받을 컴포넌트를 감싸준다.
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 />} />
          <Route path="works/:id" element={<Work />} />
        </Routes>
      </Layout>
    </BrowserRouter>
  );
};


Dynamic Route

동적 라우팅
path에 유동적인 값을 넣어서 특정 페이지로 이동하도록 구현하는 방법

라우터 경로 지정(Router.js)

  • 라우터에 상세 페이지 컴포넌트 Work를 추가하고, 상위 컴포넌트인 Works 경로에 :id를 추가한다.
    <Route path="works" element={<Works />} />
    <Route path="works/:id" element={<Work />} />

상위 페이지 구현(Works.js)

import { data } from "../shared/data";

function Works() {
  return (
    <div>
      <h3>할일 목록</h3>
      {data.map((item) => {
        return (
          <div key={item.id}>
            {item.id}
            <Link to={`/works/${item.id}`}>{item.todo}</Link>
          </div>
        );
      })}
    </div>
  );
}

export default Works;

상세 페이지 구현(Work.js)

  • useParams를 사용하여 적용한 id 값을 조회한다.

useParams

라우터를 사용할 때 지정된 파라미터 값을 가져올 수 있도록 하는 Hook

// work.js
import React from "react";
import { useParams } from "react-router-dom";
import { data } from "../shared/data"; // id를 가지고 있는 객체 배열을 저장한 data

function Work() {
  const params = useParams(); 

  const foundData = data.find((item) => { // data 객체의 id값을 가져온다.
    return item.id === parseInt(params.id); // params에 저장된 id 값과 item.id의 값이 같으면 반환
  });

  return (
    <div>
      <h3>할 일: {foundData.todo}</h3>
    </div>
  );
}

export default Work;

0개의 댓글