본문 바로가기
Today I Learned/SeSAC 웹 2기

React Router | 13주차(1)상

by suyeonnie 2025. 1. 23.

📂 오늘 배운 내용

  • SPA와 라우팅 기본 개념
  • 리액트 라우터(라이브러리) : Browser Router, Routes와 Route, 404처리
  • 라우팅 기능: Link 컴포넌트, useNavigate(), useParams(), useSearchParams()

SPA

검색 엔진 최적화(SEO)에 적합하지 않음

왜? 리액트는 html이 하나라서 페이지 별 메타데이터는 쓸 수 없음

→ Next.js의 등장! 리액트의 한계인 SEO를 해결해줌

 

React, svelte, vue.js 같은 라이브러리로 개발 가능

 

라우팅

해당 url에 맞는 페이지(컴포넌트)를 보여주는 것:

(좌) Node.js 프로젝트 (우) React

 

 


리액트 라우터 (Router)

리액트 라우터 라이브러리 설치

npm i react-router-dom@6 #버전6 지정 설치

 

- Browser Router

 

새로고침하지 않아도 새로운 컴포넌트 렌더링 해주는 기능 담당

URL마다 컴포넌트가 바뀔 때, 바뀌는 부분의 최상단에 위치해야함

 

- Routes와 Route

 

경로 매칭 `<Route> path="경로" element={ 연결할 요소 } </Route>`

- Page Not Found 처리

 

`react-router-dom` 모듈 사용하면 잘못된 Url에 대한 예외 처리 쉽게 할 수 있음!

 


라우팅 기능

 

- Link 컴포넌트

 

a태그와 Link 컴포넌트의 차이점:

  • 페이지 전환되어도 새로고침을 막아줘서 좀 더 부드러움
  • `href` 대신 `to`라는 Props속성을 사용함

- useNavigate( )

 

Link 컴포넌트 사용하지 않고 다른 페이지로 이동해야하는 경우, 뒤로 가기 등

 

 

- URL 파라미터 : useParams()

const [nameParams] = useSearchParams();

 

경로에 콜론 `:` 사용해 설정된 것

`path.props`에서 설정한 이름 = 파라미터 명

 

활용 :

1. Link to 로 이동

`/`부터 시작하지 않으면 해당 컴포넌트가 라우팅된 주소의 뒤에 해당 주소의 문자열 추가 :

 

 

2. 라우팅 처리

`App.js`에서 `board/ 파라미터` 라우팅 처리 :

 

라우터 정의는 `/:파라미터 이름` → 파라미터 이름을 가진 key값을 가진 객체를 얻을 수 있음

 

 

- 쿼리 활용 useSearchParams()

*쿼리 문자열 = `?`이후에 오는 데이터

 

검색이나 필터링 작업에서 많이 활용

useSearchParmas()가 쿼리 데이터 읽고 수정 가능

Route에서 라우팅 하지 않음:

  • 경로 변경 없이 쿼리만 변경
  • 예를 들어, `/home`에서 `localhost:3000/home?search=macbook`으로 변경되더라도 페이지 자체는 `/home`으로 유지됨

 

1. query 가져올 때는 `get('쿼리의 Key')` 함수 이용

const [queryParams] = useSearchParams(); // 쿼리 파라미터를 가져오는 객체와 설정 함수 생성
const search = queryParams.get('search'); // URL의 'search' 키에 해당하는 값을 가져옴
console.log(search); // 출력: value1

 

2. query 설정할 때는 `set` 함수 이용

const [queryParams, setQueryParams] = useSearchParams(); // 쿼리 파라미터와 설정 함수 생성

<button onClick={() => setQueryParams('search=suyeon')}>Set Query</button>

setQueryParams({ search: 'suyeon', filter: 'active' });
// 결과 URL: localhost:3000?search=suyeon&filter=active
  • `const [값, 함수] = useSearchParmas()` 활용해서 URL의 쿼리 데이터 활용 가능
  • 버튼을 클릭하면 URL이 localhost:3000?search=suyeon으로 변경
  • 여러 쿼리값 설정은 객체 사용

 

라우팅 예제 

> 더보기: header의 navigation bar

더보기

[App.js]

import { Route, Routes } from 'react-router-dom';
import Index from './pages/Index';
import NotFound from './pages/404';
import PracticeHeader from './components/PracticeHeader';
import './style/common.css';
import Student from './pages/Student';

function App() {
  return (
    <>
      <PracticeHeader />
      <Routes>
        <Route path='/' element={<Index />} />
        <Route path='/student/:name' element={<Student />} />
        <Route path='*' element={<NotFound />} />
      </Routes>
    </>
  );
}

export default App;

 

[index.js]

export default function Index() {
  return (
    <main>
      <h1>메인 페이지</h1>
    </main>
  );
}

 

[PracticeHeader.jsx]

import React from 'react';
import { Link } from 'react-router-dom';
import styled from 'styled-components';

const Nav = styled.nav`
  width: 100%;
  background-color: aliceblue;
  height: 70px;
`;

const Ul = styled.ul`
  display: flex;
  justify-content: end;
  align-items: center;
  width: 100%;
  height: 100%;
`;

// 컴포넌트에 스타일 적용
const MyLink = styled(Link)`
  color: green;
  &:hover {
    color: black;
  }
`;

const Li = styled.li`
  margin-left: 1rem;
`;

export default function PracticeHeader() {
  const style = { margin: '4px' };
  return (
    <Nav>
      <Ul>
        <Li style={style}>
          <MyLink to='/student/santa'>산타🎅</MyLink>
        </Li>
        <Li style={style}>
          <MyLink to='/student/bebe'>베베🐧</MyLink>
        </Li>
        <Li style={style}>
          <MyLink to='/student/new?name=suyeon'>searchParams</MyLink>
        </Li>
      </Ul>
    </Nav>
  );
}

 

[Student.jsx]

import { useParams, useSearchParams, useNavigate } from 'react-router-dom';

export default function Student() {
  const params = useParams(); // {name: 'anything'} // params로 가져오는 name
  const [nameParams] = useSearchParams();
  const nameQuery = nameParams.get('name'); //query로 가져오는 name

  const navigate = useNavigate();
  return (
    <main>
      <div>
        <p>학생 이름은 {params.name} 입니다.</p>
        {nameQuery && <p>실제 이름은 {nameQuery} 입니다.</p>}
      </div>

      <button onClick={() => navigate(-1)}>이전 페이지로</button>
    </main>
  );
}

 


💡 회고

 

1. 1차 팀프로젝트의 정체(?) :

1차 팀프로젝트(Node.js) 방식이 MPA(Multi-Page Application)였다. 여러 페이지를 만들고, 각 요청에 따라 적절한 페이지를 보여주는 방식인데, 당시 `res.locals`를 몰라서 각 페이지마다 사용자 정보를 전달했던 노가다의 기억이 난다 🥲

 

2. Next.js 써야 하는 이유? :

React의 약점(SEO에 부적합함)을 알게 되면서 자연스럽게 그 필요성을 이해할 수 있었다. 서버 사이드 렌더링(SSR)을 지원해 SEO 문제를 해결한다는 점에서 Next.js가 매력적인 기술임을 알게 됨.

 

3. 아니...뭔 라이브러리가 이렇게 많아? 쉽게 구현할 수 있다는 점은 분명 장점이지만, 역설적으로 vanilla JS의 중요성을 더 깊이 체감하게 되는 것같다.


🌐  참고

서울시 청년취업사관학교x코딩온 웹 풀스택 과정

- 25.react-routing

- 25.router-practice

- 25.rotuer-practice-sol