TIL 5/29

Rami·2025년 5월 29일

TodayILearn

목록 보기
48/61

useHistory()

react-router-domuseHistory() (v5 기준)는 브라우저의 history stack을 제어할 수 있게 해주는 Hook입니다.
실전에서 자주 사용하는 메서드들 중심으로 핵심만 정리드릴게요.

✅ 1. history.push(path)

👉 설명

  • 새로운 경로로 이동하면서 히스토리에 기록을 남김
  • 브라우저 ‘뒤로가기’로 돌아올 수 있음

🧪 사용 예시

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

const MyComponent = () => {
  const history = useHistory();

  const handleClick = () => {
    history.push("/detail/123");
  };

  return <button onClick={handleClick}>상세페이지로 이동</button>;
};

✅ 2. history.replace(path)

👉 설명

  • push()와 달리 히스토리 기록을 덮어씀
  • 즉, 뒤로가기로 돌아올 수 없음

🧪 사용 예시

history.replace("/login"); // 현재 페이지 기록을 로그인 페이지로 덮음

📌 언제 쓰나?

  • 로그인/회원가입 후 이전 페이지로 돌아가면 안 될 때
  • 잘못된 접근을 차단하고 새로 경로 지정할 때

✅ 3. history.go(n)

👉 설명

  • n값만큼 히스토리를 앞이나 뒤로 이동
  • n > 0: 앞으로
  • n < 0: 뒤로

🧪 사용 예시

history.go(-1); // 뒤로가기
history.go(2);  // 앞으로 두 페이지

✅ 4. history.goBack()

👉 설명

  • history.go(-1)과 동일, 뒤로 한 페이지

🧪 사용 예시

const handleBack = () => {
  history.goBack();
};

✅ 5. history.goForward()

👉 설명

  • history.go(1)과 동일, 앞으로 한 페이지

🧪 사용 예시

const handleForward = () => {
  history.goForward();
};

✅ 6. history.location

👉 설명

  • 현재 경로 정보 객체 (pathname, search, hash 등 포함)

🧪 사용 예시

console.log(history.location.pathname); // "/detail/123"
console.log(history.location.search);   // "?query=abc"

✅ 실무에서 제일 자주 쓰는 건?

메서드사용 빈도사용 용도 예시
push(path)🔥 매우 자주페이지 이동 (ex. 버튼 클릭 시)
replace(path)👍 중간로그인 등 되돌리기 막을 때
goBack()🔥 매우 자주"<- 뒤로가기" 버튼 구현


useNavigate()

react-router-dom v6에서는 기존 useHistory() 대신 useNavigate() 훅을 사용합니다.
기능은 거의 같지만, 메서드 형태와 사용 방식이 조금 다릅니다.

✅ 1. const navigate = useNavigate()

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

const MyComponent = () => {
  const navigate = useNavigate();

  const goToDetail = () => {
    navigate("/detail/123");
  };

  return <button onClick={goToDetail}>상세 페이지로 이동</button>;
};

✅ 2. navigate(path)

👉 설명

  • history.push()와 동일, 경로를 히스토리에 추가하며 이동
navigate("/home"); // 홈으로 이동

✅ 3. navigate(path, { replace: true })

👉 설명

  • history.replace()처럼 히스토리를 덮어쓰기
navigate("/login", { replace: true });

📌 예: 로그인 후 뒤로가기 막기

if (isLoggedIn) {
  navigate("/dashboard", { replace: true });
}

✅ 4. navigate(-1)

👉 설명

  • goBack()과 같음. 이전 페이지로 이동
navigate(-1); // 뒤로가기
navigate(1);  // 앞으로 가기

✅ 5. 현재 위치 접근은 어떻게?

  • useNavigate() 자체는 location 정보가 없어요.
  • 위치 정보를 얻으려면 useLocation() 사용:
import { useLocation } from "react-router-dom";

const location = useLocation();
console.log(location.pathname); // 현재 경로
console.log(location.search);   // 쿼리스트링

✅ 정리: useNavigate()에서 자주 쓰는 패턴

메서드설명예시 코드
navigate("/path")페이지 이동navigate("/home")
navigate("/path", { replace })현재 페이지 덮어쓰기 (뒤로가기 X)navigate("/login", { replace: true })
navigate(-1)브라우저 뒤로가기navigate(-1)

✅ v5와 v6 차이 핵심 요약

기능v5 (useHistory)v6 (useNavigate)
이동history.push("/path")navigate("/path")
덮어쓰기 이동history.replace("/path")navigate("/path", { replace: true })
뒤로가기history.goBack()navigate(-1)
앞으로 가기history.goForward()navigate(1)
현재 경로 확인history.locationuseLocation() 사용 필요


Link & 쿼리스트링 처리법

react-router-dom에서 경로 이동용 Link 컴포넌트 사용법
**쿼리스트링 처리법 (?id=123)**을 v5 / v6 기준 모두 비교

<a href=""> 대신 사용하는 리액트 전용 링크입니다.
페이지를 새로고침하지 않고 경로만 바꿔줍니다.

📌 v5, v6 공통 문법

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

<Link to="/about">About</Link>
<Link to={`/detail/${id}`}>상세 보기</Link>
<Link to="/search?keyword=apple">검색</Link>

✅ 2. Link에 객체 형태 전달 (pathname, search, state)

<Link
  to={{
    pathname: "/product",
    search: "?id=123",
    state: { from: "home" },
  }}
>
  상품 보기
</Link>
  • pathname: 이동할 주소
  • search: 쿼리스트링
  • state: 임의의 데이터 전달 (브라우저 주소에는 보이지 않음)

✅ 3. 쿼리스트링(Query String) 처리 방법

📌 예시 경로:

/search?keyword=apple&page=2

📦 v5: useLocation() + URLSearchParams

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

const SearchPage = () => {
  const location = useLocation();
  const query = new URLSearchParams(location.search);
  
  const keyword = query.get("keyword"); // "apple"
  const page = query.get("page");       // "2"

  return <div>검색어: {keyword}</div>;
};

📦 v6도 똑같이 사용 가능함!

// 동일한 방식
const query = new URLSearchParams(location.search);

✅ v6에서도 useSearchParams()라는 새로운 hook도 지원합니다.

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

const [searchParams, setSearchParams] = useSearchParams();

const keyword = searchParams.get("keyword");
const page = searchParams.get("page");

🔄 쿼리스트링 바꾸기 (v6 전용)

setSearchParams({ keyword: "banana", page: "1" });

✅ 4. state 값으로 데이터 전달 (URL에 안 보이게)

🔸 보내는 쪽

navigate("/detail", { state: { id: 123, from: "home" } });

🔸 받는 쪽

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

const location = useLocation();
console.log(location.state); // { id: 123, from: "home" }

✅ 마무리 요약표

기능v5 (react-router-dom@5)v6 (@6 이상)
페이지 이동history.push("/path")navigate("/path")
페이지 덮어쓰기 이동history.replace("/path")navigate("/path", { replace: true })
쿼리 읽기new URLSearchParams(location.search)useSearchParams() 또는 URLSearchParams
쿼리 쓰기직접 문자열 조작setSearchParams({ key: val })
state로 값 전달history.push(path, { state })navigate(path, { state })
state 값 받기location.state동일


searchParams, state

✅ 1. searchParams를 활용한 페이지네이션 구현 예시

(쿼리스트링으로 ?page=2처럼 처리)

✅ 2. state를 활용한 로그인 후 리디렉션 예시

(로그인 후 원래 있던 페이지로 돌아가기)

두 가지를 실전 예제 중심으로 보여드릴게요.


✅ 예제 1: searchParams로 페이지네이션 구현

🧩 주소 예시:

/posts?page=2

📦 PostList.tsx

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

const PostList = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const page = parseInt(searchParams.get("page") || "1", 10);

  const handleNext = () => {
    setSearchParams({ page: String(page + 1) });
  };

  const handlePrev = () => {
    setSearchParams({ page: String(page - 1) });
  };

  return (
    <div>
      <h2>{page} 페이지 게시글</h2>
      {/* 게시글 리스트 fetch 등 생략 */}
      <button onClick={handlePrev} disabled={page <= 1}>이전</button>
      <button onClick={handleNext}>다음</button>
    </div>
  );
};

export default PostList;

🔍 주요 포인트

코드설명
useSearchParams()쿼리스트링을 상태처럼 다룸
searchParams.get("page")현재 page 번호 읽기
setSearchParams({ page })주소 변경 (URL에 반영됨)

✅ 예제 2: 로그인 후 원래 있던 페이지로 리디렉션 (with state)


🧩 상황:

  • /protected 같은 보호된 페이지는 로그인 후에만 접근 가능
  • 로그인 안 한 상태에서 접근하면 /login으로 이동
  • 로그인 완료 후 원래 페이지로 되돌아가기

📦 ProtectedRoute.tsx (로그인 체크)

import { Navigate, useLocation } from "react-router-dom";

const ProtectedRoute = ({ children }: { children: JSX.Element }) => {
  const isLoggedIn = false; // 실제로는 context나 recoil 등에서 가져옴
  const location = useLocation();

  if (!isLoggedIn) {
    return <Navigate to="/login" state={{ from: location }} replace />;
  }

  return children;
};

export default ProtectedRoute;

📦 Login.tsx (로그인 후 이동)

import { useNavigate, useLocation } from "react-router-dom";

const Login = () => {
  const navigate = useNavigate();
  const location = useLocation();
  const from = location.state?.from?.pathname || "/";

  const handleLogin = () => {
    // 로그인 처리 후
    navigate(from, { replace: true });
  };

  return (
    <div>
      <h2>로그인 페이지</h2>
      <button onClick={handleLogin}>로그인하기</button>
    </div>
  );
};

export default Login;

🔍 주요 포인트

코드설명
state={{ from: location }}현재 위치를 statelogin에 전달
location.state?.from?.pathname로그인 후 다시 돌아올 경로
navigate(from, { replace: true })히스토리 덮어쓰기 방식으로 돌아감

✅ 실무 팁 요약

상황추천 방식
쿼리스트링 기반 검색/페이지네이션useSearchParams()
로그인 후 이전 위치로 복귀useNavigate() + state
상태를 URL에 보이고 싶지 않다면state 사용, 쿼리스트링은 사용하지 않기


${movieId} vs :movieId

/movies/${movieId}"/movies/:movieId"비슷해 보여도 완전히 다른 목적으로 사용됩니다.
${movieId} : 페이지 이동이나 링크를 걸 때
:movieId : 라우터에서 경로를 정의할 때

✅ 1. /movies/:movieId경로를 정의할 때(Route path 설정)

📌 의미

  • :movieId는 "동적으로 변하는 값"을 의미합니다.
  • 예: /movies/123, /movies/abc 등 다양한 movieId에 대응 가능

🧩 예시 (라우팅 설정)

// react-router-dom v6
import { Routes, Route } from "react-router-dom";
import MovieDetail from "./MovieDetail";

<Routes>
  <Route path="/movies/:movieId" element={<MovieDetail />} />
</Routes>

✅ 2. /movies/${movieId}링크를 걸거나 이동할 때

📌 의미

  • 실제 URL 문자열을 구성할 때 사용
  • 문자열 템플릿(template literals)을 통해 실제 경로를 완성
// movieId = 123일 때
<Link to={`/movies/${movieId}`}>상세 보기</Link>

// 또는
navigate(`/movies/${movieId}`);

✅ 정리 비교

용도사용 예설명
라우터에서 경로 정의/movies/:movieId:movieId는 "변수", 어떤 id에도 대응 가능
링크/이동 시 경로 작성/movies/${movieId}실제 값이 들어간 URL로 이동함

✅ 같이 쓰는 예제 흐름

  1. 라우터 정의:
<Route path="/movies/:movieId" element={<MovieDetail />} />
  1. 이동/링크:
<Link to={`/movies/${movie.id}`}>상세 보기</Link>
  1. 컴포넌트 내부에서 movieId 꺼내기:
import { useParams } from "react-router-dom";

const MovieDetail = () => {
  const { movieId } = useParams();
  return <div>영화 ID: {movieId}</div>;
};
profile
YOLO

0개의 댓글