[React] React Router 사용하기

jwww·2023년 7월 22일
0

React

목록 보기
4/11

리액트에서 링크 이동을 하려면 react-router-dom을 사용해야한다.

라우팅이란?

라우팅은 사용자가 요청한 URL에 따라 알맞는 페이지를 보여주는 것이다.

MPA와 SPA

원래 사용하던 MPA(Multi Page Application) 방식은,
사용자가 다른 페이지로 이동할 때마다 새로운 HTML을 받아오고, 페이지를 로딩할 때마다 서버에서 CSS,JS, 이미지 등의 리소스를 전달받아 화면에 보여주었다.

리액트에서 사용하는 SPA(Single Page Application) 방식은 한 번만 HTML을 받아와 웹 애플리케이션을 실행시키고 이후에는 필요한 데이터만 받아와서 화면에 업데이트 해준다.

사용자 인터렉션이 적은 정적인 페이지는 MPA 방식이 적합하지만, 사용자 인터렉션이 많고 다양한 정보를 제공하는 모던 웹 애플리케이션은 새로운 페이지를 보여줘야 할 때마다 서버 자원을 많이 사용하는 MPA 방식이 적합하지 않다.

React Router 란?

리액트에서 페이지를 이동할 때 필요한 라이브러리이다.
리액트 라우팅 관련 라이브러리 중 가장 오래되었고 많이 사용되고 있다.

즉, React-Router는 신규 페이지를 불러오지 않고 각각의 url에 따라 선택된 데이터를 하나의 페이지에서 렌더링 해주는 라이브러리라고 볼 수 있다.

v3버전까지는 react-router 모듈 하나만 사용할 수 있었는데 v4버전 이후 웹 개발자를 위한 react-router-dom과 앱 개발자를 위한 react-router-native가 등장했다.

  • react-router : 웹 & 앱
  • react-router-dom : 웹
  • react-router-native : 앱

웹에서 사용할 것이기 때문에 react-router-dom 을 사용한다.

기본 사용법

(1) react-router-dom 라이브러리 설치

npm install react-router-dom

(2) 컴포넌트 분리

페이지를 이동해도 항상 있는 Header 컴포넌트
홈화면을 나타내는 Home 컴포넌트
소개페이지를 나타내는 About 컴포넌트가 있다고 가정하자.

(3) react-router-dom 사용

가장 바깥쪽은 <BrowserRouter> 로 감싸준다.
모든 페이지에 공통적으로 나와야하는 컴포넌트를 제외하고 <Routes>로 감싼다.

react-router-dom 내장 컴포넌트

  • <BrowserRouter> : history API를 사용해 URL과 UI를 동기화하는 라우터
  • <Routes> : 자식 컴포넌트인 <Route>중 매치되는 첫 번째 요소를 렌더링한다. 사용하지 않을 경우 매칭되는 모두를 렌더링한다.
  • <Route> : 속성 path에 설정된 URL과 현재 경로가 일치하면 해당하는 컴포넌트를 렌더링한다.
    path 속성에 경로, element 속성에 컴포넌트를 넣어준다.
    path="/" 는 메인페이지, path="/about"
  • <Link> : <a>와 비슷한 역할을 한다. to 속성에 설정된 링크로 이동한다. 기록이 history 스택에 저장된다.
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import Header2 from './component/Header2';


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

export default App;

여기서 소개 부분을 누르면 소개 페이지로 이동하게 하려면 <Link>를 사용한다.
원래 웹페이지에서 링크를 보여줄 때 <a> 를 사용하지만 <a>는 페이지를 새로 불러오기 때문에 리액트 라우터를 사용하는 프로젝트에서는 <Link>를 사용한다.

<Link to="경로">경로이름</Link>
import { Link } from 'react-router-dom';

export default function Home(){
    return <>
        <header>홈 화면</header>
        <Link to="/about">소개</Link>
    </>
}

이제 소개를 누르면 소개 페이지로 이동할 수 있다.


영단어

예시로 Day1, Day2, Day3 날짜를 만들어두고 날짜를 클릭하면 그 날짜에 해당하는 영단어들이 나오는 페이지를 만들어보자.

1. 더미 데이터 만들기

db라는 폴더를 만든후 json 파일을 만든다.
key는 "days", "words" 두 종류. words에는 id, day, eng, kor, isDone가 들어간다.

{
    "days" : [
        { "id" : 1, "day" : 1 },
        { "id" : 2, "day" : 2 },
        { "id" : 3, "day" : 3 }
    ],
    "words" : [
        {
            "id" : 1,
            "day" : 1,
            "eng" : "book",
            "kor" : "책",
            "isDone" : false
        },
        {
            "day": 1,
            "eng": "purple",
            "kor": "보라",
            "isDone": false,
            "id": 13
        },
        {
            "id": 3,
            "day": 2,
            "eng": "car",
            "kor": "자동차",
            "isDone": false
        },
        ...
    ]
}

2. 컴포넌트 구성

App.js

App.js 하위 컴포넌트

  • 헤더부분인 Header 컴포넌트
  • 날짜 리스트를 보여주는 DayList 컴포넌트
  • 단어 테이블을 보여주는 Day 컴포넌트
  • 잘못된 주소를 입력할 경우 나오는 EmptyPage 컴포넌트
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Header from './component/Header';
import DayList from './component/DayList';
import Day from './component/Day';
import EmptyPage from './component/EmptyPage';

function App() {
  return (
      <div className="App">
        <BrowserRouter>
          <Header />
          <Routes>
            <Route path="/" element={<DayList/>} />
            <Route path="/day/:day" element={<Day/>} />
            <Route path="*" element={<EmptyPage/>} />
          </Routes>
        </BrowserRouter>
      </div>
  );
}

export default App;

Header.js

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

export default function Header(){
    return <div className="header">
        <h1>
            <Link to="/">토익 영단어(고급)</Link>
        </h1>
        <div className="menu">
            <a href="#x" className="link">단어 추가</a>
            <a href="#x" className="link">Day 추가</a>
        </div>
    </div>
}
  • import { Link } from 'react-router-dom'
    : Link 사용
  • <Link to="/">토익 영단어(고급)</Link>
    : 토익 영단어 클릭하면 메인화면으로 이동.

DayList.js

import { Link } from 'react-router-dom';
import dummy from "../db/data.json";

export default function DayList() {
    return <ul className="list_day">
        {dummy.days.map(day => (
            <li key={day.id}>
                <Link to={`/day/${day.day}`}>Day {day.day}</Link>
            </li>
        ))}
    </ul>;
}
  • {dummy.days.map(day => ()
    : days에 있는 모든 일자에 function을 실행한다는 의미.

  • import dummy from "../db/data.json"
    : 더미데이터를 사용하기 위한 코드.

  • <Link to={/day/${day.day}}></Link>
    : day1 / day2 / day3 날짜 별로 link 이동이 달라야하므로 day.day로 받아온다.

Day.js

import dummy from "../db/data.json"
import { useParams } from 'react-router-dom';

export default function Day() {
    // dummy.words
    const day = useParams().day;
    const wordList = dummy.words.filter(word => (
        word.day === Number(day)
    ))
    return <>
        <h2>Day {day}</h2>
        <table>
            <tbody>
                {wordList.map(word => (
                    <tr key={word.id}>
                        <td>{word.eng}</td>
                        <td>{word.kor}</td>
                    </tr>
                ))}
            </tbody>
        </table>
    </>
}
  • const wordList = dummy.words.filter(word => (word.day === Number(day)))
    : dummy 데이터의 words를 사용하는데 해당하는 day의 word를 렌더링해야하므로 filter를 사용해 word 키가 가지고 있는 day와 days의 day가 일치하는 단어를 반환한다.

EmptyPage.js

이 페이지는 잘못된 링크로 접근했을 때 나오는 페이지다.

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

export default function EmptyPage() {
    return (
        <>
            <h2>잘못된 접근입니다.</h2>
            <Link to="/">돌아가기</Link>
        </>
    )
}

완성 시 아래처럼 페이지가 나온다.

Day1 클릭 시,

Day2 클릭 시,

Day3 클릭 시,

profile
퍼블리셔 공부 블로그 입니다

0개의 댓글