Studying/React

리액트 공부하기 - React Router 리액트 라우터 심화공부

creamymood 2025. 5. 23. 00:27

 

뭐야 .. ? 할게 넘 많잖아 .. ?

 

모야.. 실무에서 쓰려니까 뭐 더 많이 알아야 하잖아?

프로젝트에서 페이지는 아주 많아질테니.. 라우터 추가 공부 필요하겠잖아 ?


 

라우터의 기초 내용은 아래 링크에서 볼 수 있다.

 

 

리액트 공부하기 - React Router 리액트 라우터

1. 리액트 라우터란?2. 리액트 라우터 사용하는 법3. 궁금증 두가지. (왜 설치를 따로해야하는가? 주소를 이동하는건데 새로고침이 안된다고 ?!)4. 리액트 라우터 주요 컴포넌트5. 리액트 라우터 주

creamymood.tistory.com


 

1. useNavigate() 이런 훅을 쓸 때, 바로 쓰진 못하고 변수에 할당에서 쓰더라.

이유는 ? ↓

더보기

useNavigate() 같은 훅을 바로 호출해서 못 쓰고 변수에 할당해서 쓰는 이유는?

const navigate = useNavigate();
navigate('/home');
  • React 훅은 함수 컴포넌트 또는 커스텀 훅 안에서만 호출 가능해.
  • 훅은 호출되는 위치(컴포넌트 렌더링 과정)에서 내부 상태나 컨텍스트를 관리하기 위해 만들어졌기 때문이야.
  • 그래서 훅을 호출할 때는 결과(함수, 상태값 등)를 변수에 받아서 사용해야 해.
  • useNavigate()는 함수를 반환하는 훅이기 때문에, 반환된 함수를 변수에 저장한 후 호출해서 경로를 이동해.
  • 훅이 반환하는 함수를 직접 호출하는 건 가능하지만, useNavigate()를 호출하고 바로 뒤에 경로를 넣어서 쓰는 문법(예: useNavigate()('/home'))는 일반적이지 않고 가독성도 떨어짐.

모든 훅이 다 그런가?

  • 네, React 내장 훅(useState, useEffect, useContext 등)과 커스텀 훅 모두 호출 결과를 변수에 할당하거나 바로 사용해야 함.
  • 훅은 반드시 React 함수 컴포넌트의 최상위 또는 다른 훅 안에서 호출돼야 한다는 규칙도 있어(조건문이나 반복문 안에서 호출하면 안 됨).

이유는 아래 블로그에서 조금 더 자세히 다뤄보았다.


 

리액트 공부하기 - hooks를 최상단에 작성 해야 하는 이유? 변수에 담아서 사용하는 이유?

훅이란?아래 블로그에서 자세히 읽어볼 수 있다. 리액트 공부하기 - custom hooks? 그냥 함수 차이?custom hooks를 공부하며 헷갈리게 된 또 기본 개념- 다시 짚고 갑시다.우선 훅(hook)이 뭘까. 리액트(Reac

creamymood.tistory.com

 

 

 

 

2. 페이지를 보호할 땐, 껍데기wrapper를 하나  만들어서 씌울 수 있다. 🍑

 

 

3. 라우터에서 element 부분

더보기

리액트 라우터(React Router)에서 element는 특정 경로(URL)에 도달했을 때 화면에 렌더링할 컴포넌트를 지정하는 부분입니다.

기본 문법 예시

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

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

element의 역할

  • element={<Home />}는 / 경로일 때 <Home /> 컴포넌트를 렌더링하라는 의미입니다.
  • 즉, element에는 JSX 형태로 렌더링하고 싶은 컴포넌트 인스턴스를 넣는다고 생각하면 돼요.

추가 설명

path URL 경로를 지정합니다.
element 해당 경로에 도달했을 때 보여줄 컴포넌트를 JSX 형태로 지정합니다.

예를 들어 /about으로 이동하면 <About /> 컴포넌트가 보이는 거죠.


자주 하는 실수

❌ element={About} 이렇게 쓰면 오류가 납니다.
✅ 반드시 JSX 형태로: element={<About />}

 

 

 

4. <Navigate to="..." replace />에서 replace란? 

더보기

<Navigate to="/mypage" replace />에서 replace는 고정 문법이라기보다 상황에 따라 쓰는 옵션이야.

1. <Navigate to="..." replace />에서 replace란?

  • 기본적으로 Navigate를 사용하면 현재 페이지를 스택에 쌓고 새 페이지로 이동해.
  • replace를 쓰면 브라우저 히스토리에서 현재 페이지를 새 페이지로 대체해.
  • 즉, 사용자가 뒤로가기 했을 때 리다이렉트된 페이지로 다시 돌아오는 걸 방지해줘.
  • 로그인 리다이렉트처럼 이전 페이지로 돌아가면 안 되는 경우에 주로 사용해.
<Navigate to="/mypage" replace />
  • replace 없으면 뒤로가기 시 로그인 페이지로 돌아감
  • replace 있으면 로그인 페이지 히스토리 기록이 없어 뒤로가기 시 이전 페이지로 이동

replace를 쓰면, 브라우저 '뒤로 가기'를 눌렀을 때 리디렉션 이전 페이지로 돌아가지 않아!


🔍 어떻게 동작하냐면

<Navigate to="/mypage" replace />

이렇게 하면:

  • 현재 URL을 /mypage로 바꾸되, 브라우저 히스토리에 /login을 남기지 않아.
  • 그래서 사용자가 브라우저에서 뒤로가기를 눌러도 /login으로 다시 못 돌아감.

👀 예를 들어서

replace ❌ 없는 경우:

  1. 사용자가 /login 들어감
  2. 로그인 성공 → Navigate to="/mypage" (기본은 replace: false)
  3. 브라우저 히스토리: /login → /mypage
  4. 사용자가 뒤로가기 누르면... 👉 다시 /login으로 감! (근데 이미 로그인된 상태니까 이상함)

replace ✅ 있는 경우:

  1. 사용자가 /login 들어감
  2. 로그인 성공 → Navigate to="/mypage" replace
  3. 브라우저 히스토리: /mypage만 남음
  4. 뒤로가기 눌러도 👉 /login은 히스토리에 없으니까 못 감

📌 요약

  • replace는 히스토리 스택을 덮어씀
  • 뒤로가기 눌렀을 때 이전 페이지로 안 돌아가게 함
  • 보통 로그인/로그아웃/자동 리디렉션 시 사용

**히스토리는 없어서, 뒤로가기로는 접근이 안되지만..

wrapper로 보호 컴포넌트로 감싸줘야 url에 쳐서 접근하는 것도 막을 수 있음.

 

5. 실무에서 자주 쓰이는 router hook 

더보기

실무에서 자주 쓰이는 React Router 훅 정리

 

이름 용도  예시 및 설명
useNavigate 프로그래밍 방식으로 페이지 이동을 할 때 사용 const navigate = useNavigate(); navigate('/home');
useParams URL 파라미터 값을 가져올 때 사용 /user/:id 경로에서 const { id } = useParams();
useLocation 현재 URL, 쿼리스트링, 상태 등 위치 정보를 얻을 때 사용 const location = useLocation(); console.log(location.pathname);
useMatch 현재 경로가 특정 경로와 일치하는지 확인할 때 사용 const match = useMatch('/profile/:id');
<Outlet> 중첩 라우팅에서 자식 컴포넌트를 렌더링할 때 사용 상위 라우트 컴포넌트에 배치해 하위 라우트 렌더링
<Navigate> 리다이렉션(강제 경로 이동) 시 사용 <Navigate to="/login" replace />

 

6. useNavigate의 다양한 옵션

더보기

<Navigate>의 replace 외에 주요 속성들

<Navigate>는 리다이렉트를 위한 컴포넌트라서 크게 복잡하지 않지만, 몇 가지 중요한 속성 있어.


속성명 설명  기본값 / 예시
to 이동할 경로 지정 (필수) /mypage, { pathname: '/home' } 등
replace 현재 히스토리 기록을 대체할지 여부 false (기본값), true로 설정하면 replace 동작
state 이동 시 전달할 상태 데이터 { from: '/login' } 등
relative 상대 경로로 해석할지 여부 (React Router v6.12부터) false 기본값

조금 더 자세히

<Navigate 
  to="/mypage" 
  replace={true} 
  state={{ from: '/login' }} 
/>
  • to: 이동할 경로. 문자열이나 객체로 쓸 수 있어.
  • replace: true면 히스토리에서 현재 페이지를 새 페이지로 대체. 뒤로가기 시 이전 페이지로 돌아가지 않음.
  • state: 이동할 때 추가 데이터를 넘길 수 있어. 나중에 useLocation() 훅에서 location.state로 받을 수 있어.
  • relative: 경로를 상대 경로로 해석할지 설정. 잘 쓰이지는 않음.

참고로 useNavigate 함수도 비슷하게 옵션을 줄 수 있어요

navigate('/mypage', { replace: true, state: { from: '/login' } });
  • navigate 함수는 두 번째 인자로 옵션 객체를 받음
  • 여기서도 replace와 state를 설정 가능!

 

7. 너무 추상적이어서 볼 때 마다 헷갈리던 outlet . 아래 내용 읽고 조금은 해결

더보기

네브바는 항상 화면에 보여야 해

  • 네브바 안에 "로그인 / 검색 / 로고" 버튼이 있어
  • 이 버튼들을 클릭하면 각각 로그인 페이지 / 검색 페이지 / 로고 페이지로 이동해야 해
  • 근데 그때도 네브바는 계속 보여야 해

🧸 그림으로 표현하면 이런 구조!

전체 App
├─ NavBar (항상 보여야 해!)
│  ├─ [로그인] [검색] [로고] ← 버튼들
│  └─ Outlet 자리 → 여기에 로그인/검색/로고 페이지가 하나씩 바뀌며 들어옴

🔨 구현 흐름 예시

1. NavBar.js

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

function NavBar() {
  return (
    <div>
      <nav style={{ background: '#eee', padding: '10px' }}>
        <Link to="/login">로그인</Link> | 
        <Link to="/search">검색</Link> | 
        <Link to="/logo">로고</Link>
      </nav>

      {/* 이 자리에 해당 페이지가 바뀌며 들어옴 */}
      <Outlet />
    </div>
  );
}

export default NavBar;

<nav>로 감싸진건 항상 보여야 하는 고정된 레이아웃

그 밑에 outlet으로 된 건, 밑에 app.jsx에서 라우터로 감싸진

NavBar 자식 요소들이 모두 렌더링 될 수 있는 자리!


2. App.js

import { BrowserRouter, Routes, Route } from "react-router-dom";
import NavBar from "./NavBar";
import Login from "./pages/Login";
import Search from "./pages/Search";
import Logo from "./pages/Logo";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<NavBar />}>
          <Route path="login" element={<Login />} />
          <Route path="search" element={<Search />} />
          <Route path="logo" element={<Logo />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}
<NavBar /> 항상 보여야 하는 레이아웃 (고정)
<Outlet /> 현재 URL에 따라 Login, Search, Logo 페이지 중 하나가 여기에 들어옴
<Route path="/" element={<NavBar />} > ... </Route> 이 구조 덕분에 NavBar는 계속 보이고, 그 아래 내용만 바뀜

지난 영화 페이지 프로젝트를 기준으로

🧁 쉽게 비유하면

🍰 케이크(전체 화면) = Layout

  • 항상 보이는 틀: 네브바, 푸터 등 (고정된 것)
  • 안에 바뀌는 크림: 각 페이지의 내용 (Outlet으로 들어감)

 

 

8. 동적 파라미터 설정하기

더보기

동적 파라미터란?

예를 들어, 우리 웹사이트에 여러 도시의 정보를 보여주는 페이지가 있다고 생각해본다면,

/detail/seoul  
/detail/tokyo  
/detail/newyork

이렇게 도시 이름만 바뀌는 페이지가 있으면, 각각 따로 라우트를 만들지 않고 하나의 라우터로 처리할 수 있다.

그걸 가능하게 해주는 게 바로 동적 파라미터

어떻게 쓰는지?

1. Route에서 정의:

<Route path="/detail/:city" element={<Detail />} />

여기서 :city는 변하는 값이 들어올 자리다.
예를 들어 /detail/seoul로 들어오면, city는 "seoul"이 되는 것.


2. navigate 할 때

navigate(`/detail/${searchInputValue}`)

만약 searchInputValue가 "tokyo"라면,
이건 결국 이렇게 되는 것:

navigate("/detail/tokyo")

3. Detail 컴포넌트에서 그 값 꺼내기:

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

const Detail = () => {
  const { city } = useParams();  // city는 URL의 값
  return <div>{city}의 정보입니다.</div>;
}

 

궁금한 것!

// 라우터 설정 
<Route path='/detail/:city' element={<Detail />} />

라우터에서의 동적파라미터에서 : 뒤에는 아무거나 들어가는 건가?

 

=>

:뒤에 오는 단어는  마음대로 정할 수 있는 이름
단, 그 값은 URL의 일부로부터 받아오는 변수명이기 때문에 의미 있게 지으면 좋다.


예시 1: 도시 이름일 때

<Route path="/detail/:city" element={<Detail />} />
  • 여기서 :city는 URL에서 받아오는 값이야.
  • 실제 URL이 /detail/seoul이면, city = "seoul"이 됨.

예시 2: 유저 ID일 때

<Route path="/user/:userId" element={<UserProfile />} />
  • 이 경우 URL이 /user/123이면, userId = "123"이 됨.

 규칙 정리

  • : 뒤에는 원하는 이름을 붙여도 됨 (:id, :name, :productSlug 등등).
  • 단, useParams()로 꺼낼 때도 그 이름을 그대로 써야 해.

예:

<Route path="/post/:postId" element={<Post />} />
// Post.jsx
const { postId } = useParams();  // postId로 꺼내야 함!

이렇게 하면 안 됌:

<Route path="/post/:id" element={<Post />} />

// 그런데 이렇게 꺼냄
const { postId } = useParams();  // ❌ undefined가 나와

왜냐하면 :id라고 했으니까, id로 꺼내야 맞음.