React JS #10 라우터 구현 react-router-dom - 초보자를 위한 리액트 강좌

Robyn·2023년 4월 3일
0

공부 출처

라우터 구현을 위해 react router dom을 설치해야한다.
터미널에 다음과 같이 입력한다.

npm install react-router-dom

App.js에 가서 BrowserRouter, Route, Switch 이렇게 세 개를 import한다.

import { BrowserRouter, Route, Switch } from "react-router-dom";

우선 App 전체를 BrowserRouter로 감싸준다.

import Header from "./component/Header";
import DayList from "./component/DayList";
import Day from "./component/Day";
import { BrowserRouter, Route, Switch } from "react-router-dom";

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Header></Header>
        <DayList></DayList>
        <Day></Day>
      </div>
    </BrowserRouter>
  );
}

export default App;

Header는 모든 페이지에 나와야하니까 Header 다음을 Switch로 감싸준다.
참고로 다음 사진이 Header이다.

코드는 다음과 같다.

import Header from "./component/Header";
import DayList from "./component/DayList";
import Day from "./component/Day";
import { BrowserRouter, Route, Switch } from "react-router-dom";

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Header></Header>
        <Switch>
          <DayList></DayList>
          <Day></Day>
        </Switch>
      </div>
    </BrowserRouter>
  );
}

export default App;

이렇게 하면 Switch 내부는 url에 따라 각각 다른 페이지를 보여줄 것이다.
Switch 외부는 모든 페이지에 공통으로 노출된다.

이제 Route를 사용하겠다.

<Route path="/"></Route>

여기서 path에 /만 적는다면 첫 페이지를 의미한다.

첫 페이지에선 DayList(날짜들)를 보여주면 되겠다.

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Header/>
        <Switch>
          <Route path="/">
            <DayList/>
          </Route>
          <Day/>
        </Switch>
      </div>
    </BrowserRouter>
  );
}

이제 Route path="/day"를 만들고 그 안에 Day를 넣으면 되겠다.

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Header />
        <Switch>
          <Route path="/">
            <DayList />
          </Route>
          <Route path="/day">
            <Day />
          </Route>
        </Switch>
      </div>
    </BrowserRouter>
  );
}

여기까지 하고 브라우저를 보려고 했는데
export 'Switch' (imported as 'Switch') was not found in 'react-router-dom'
라고 나온다.

검색해보니 Switch 대신 Routes를 써야하나보다.
그리고 심지어 안에 컴포넌트를 넣는 게 아니라 element로 속성값 추가하는 것 같이(맞나?) 적어야하더라.

import Header from "./component/Header";
import DayList from "./component/DayList";
import Day from "./component/Day";
import { BrowserRouter, Route, Routes } from "react-router-dom";

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

export default App;

이렇게 적으니까 된다.
(구글링으로 해결... https://velog.io/@kcdoggo/Switch-is-not-exported-from-react-router-dom-에러 이 분께 감사드린다.)

근데 영상에서는 Route에 exact라고 안 적으면 /day라고 적어도 /가 포함되어있으므로 DayList가 나온다고하는데 바뀐 코드(내가 적은 코드)에서는 exact 안 썼는데도 /day로 가니까 Day 컴포넌트가 나왔다.

이제 Day1, Day2, Day3를 넣으면 각각의 날짜 단어들로 이동하도록 링크를 걸어주겠다.
리액트 라우터에서는 Link to를 사용한다.

DayList.js에 Link를 import해주고 다음과 같이 작성한다.

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

export default function DayList() {
    console.log(dummy);
    return (
        <ul className='list_day'>
            {dummy.days.map(day => (
                <li key={day.id}>
                    <Link to='/day'>Day {day.day}</Link>
                </li>
            ))}
        </ul>
    );
} 

Link css를 위해 다음과 같이 index.css에 적는다.

.list_day a{
  display: block;
  padding: 20px 0;
  font-weight: bold;
  color: #fff;
  text-align: center;
  border-radius: 10px;
  background-color: dodgerblue;
}

그럼 다음과 같이 된다.

그런데 a href가 아니라 Link to인데 왜 css에는 a라고 적는지 궁금하다.
둘이 다른 거라면서요.

개발자 도구에서는 이렇게 나오는 걸 볼 수 있다.

Header도 클릭하면 홈으로 이동할 수 있게끔 Link to를 걸어주겠다.
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>
}

이제 '토익 영단어(고급)'을 누르면 메인으로 이동한다.

이제 day1을 누르면 1로 가고 day2를 누르면 2로 가도록 해보겠다.

DayList.js를 다음과 같이 수정한다.

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

export default function DayList() {
    console.log(dummy);
    return (
        <ul className='list_day'>
            {dummy.days.map(day => (
                <li key={day.id}>
                    <Link to={`day/${day.day}`}>Day {day.day}</Link>
                </li>
            ))}
        </ul>
    );
} 

day.day는 data.json에서 다음 부분을 의미한다.

{
    "days": [
        {"id":1, "day":1},
        {"id":2, "day":2},
        {"id":3, "day":3}

여기서 "day":~ 이 부분들을 의미함.

day2를 누르면 주소창이 이렇게 변한다. 각 날짜에 맞춰 잘 이동하고 있다.

http://localhost:3000/day/2

App.js에서 다음과 같이 수정해준다.

          <Route path="/day/:day" element={<Day />}>
          </Route>

useParam은 무엇인가?
챗지피티한테 물어보니까 이렇게 나오고 어떻게 사용하는지도 가르쳐줬다.

useParams는 react-router-dom 패키지에서 제공되는 React Hook으로, URL의 동적 세그먼트에서 파라미터 값을 추출하는 데 사용됩니다.
예를 들어, /users/:id와 같은 URL이 있다면, id라는 동적 세그먼트가 포함되어 있습니다. useParams를 사용하면 이 동적 세그먼트에서 id를 추출하여 사용할 수 있습니다.

Day.js에서

import { useParams } from 'react-router-dom';
	const a = useParams();
    console.log(a);

이런 코드를 추가하면

브라우저에서 day1을 클릭했을 때

이렇게 콘솔에 나온다.

Day.js에 다음과 같이 적어준다.

const day = useParams().day;

혹은

const {day} = useParams();

그리고 숫자랑 비교를 해야하기 때문에 다음과 같이 수정해준다.

    const wordList = dummy.words.filter(word => (
        word.day === Number(day)
    ))

주소창에 day/ 다음에 아무거나 입력했을 때 empty page가 나오도록 하기 위해 EmptyPage 컴포넌트를 만든다.

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

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

App.js에 다음과 같이 적었으나 안되는데...

          <Route element={<EmptyPage/>}>
          </Route>

길을 잃었다...
어딜 가야 할까...

https://velog.io/@jisubin12/React-코딩앙마-리액트-기초강좌-10.-라우터-구현-react-router-dom 이런 글을 발견하긴했는데 여전히 어떻게 해야할지 모르겠다.

          <Route path="/day/*" element={<EmptyPage/>}>
          </Route>

맨 밑에 이걸 추가했는데 안 됨

0개의 댓글