chorock.page
소개글시리즈프로젝트
© 2026 chorock.page
← 목록으로
Next.js 기초 - App Router · 10/11
← 이전 글다음 글 →
Next.jsweb

App Router (10) - 우아하게 에러 핸들링하기 (error.tsx)

2026.09.28 · 3분 읽기 · 조회 0

목차
error.tsxerrorresetrouter.refreshStartTransition

error.tsx

데이터 페칭을 할 때 보통 try/catch 문을 많이 사용한다.

try {
  await response = ...
 
} catch(error) {
 
  return <div>에러...</div>
}

이런 식으로 예외처리를 해주어도 좋으나, 모든 데이터 페칭 로직에 catch 내부 값을 따로 적어주는 것은 비효율적이고 코드가 복잡해질 수 있다. 이럴 때 error.tsx 파일을 사용한다.

같은 폴더 내에 error.tsx 파일을 만든다.

"use client"
 
export default function Error(){
 
  return <div>에러 발생</div>
}

다음과 같이 에러 발생 시 보여줄 값을 리턴해주면, catch 문 없이도 에러 발생 시 해당 에러 컴포넌트를 띄워줄 수 있다. error.tsx도 역시 하위 페이지의 오류까지 한 번에 처리할 수 있다.
당연히 브라우저에서 에러를 띄워줄 수 있어야 하기 때문에 "use client"로 클라이언트 컴포넌트로 만들어준다.

error

export default function Error({error} : {error : Error}){
  
  return <div>에러 발생</div>
}

error.tsx의 컴포넌트는 첫 번째 파라미터로 error 값을 받을 수 있으며, 해당 객체에는 오류의 내용이 들어있다. 자바스크립트의 기본 Error 타입이다.
error.message 로 에러 내용을 확인 가능하다.

reset

export default function Error({reset} : {reset : () => void }){
  
  return <div>에러 발생</div>
}

두 번째 인자로 reset이라는 함수를 받을 수 있다. 타입은 () => void이다. 해당 함수는 에러가 발생한 페이지를 복구하기 위해, 다시 한 번 컴포넌트들을 렌더링 시켜보는 기능을 지닌다.

export default function Error({reset} : {reset : () => void }){
  
  return 
    <>
      <div>오류 발생</div>
      <button onClick={() => reset}>다시시도</button>
    </>
}

이렇게 적으면 다시시도 버튼을 누르면 재렌더링 시도를 한다.
주의할 점은, 서버에 데이터 페칭을 다시 보내는 것이 아니라, 클라이언트 측에서 이미 서버에서 받은 데이터로 재렌더링 시도만 한다는 것이다.

<button onClick={() => window.location.reload()}>다시시도</button>

차라리 window 객체를 이용해 새로고침을 시키는게 나을 수도 있다. 이러면 서버에 다시 페칭요청을 하니말이다. 하지만 이렇게 하면 state 정보가 다 날아갈 것이다.

router.refresh

좀 더 우아하게 새로고침을 시켜보자. 상태를 유지시키면서

import { useRouter } from "next/navigation";
 
const router = useRouter();

라우터 훅을 next/navigation 에서 받아온다.

<button onClick={() => router.refresh()}>다시시도</button>

재시도 버튼 클릭 시 router.refresh 메서드를 실행하게 만든다.
해당 메서드는 현재 페이지에 필요한 서버 컴포넌트를 다시 next 서버에서 렌더링시키는 역할을 한다.
당연히 데이터 페칭이 다시 일어난다.

<button
  onClick={() => {
    router.refresh();
    reset();
  }}
>
  다시 시도
</button>

그리고 이제 reset 함수를 호출해 브라우저 사이드를 재렌더링한다.
reset은 에러상태를 초기화하고, 컴포넌트들을 다시 렌더링하기 때문에 이것을 활용해 에러상태를 초기화해주어야 한다.

여기서 router.refresh()는 사실 비동기적으로 동작한다. 때문에 refresh 가 끝나기도 전에 reset이 실행되어 오류가 고쳐지지 않는다.

<button
  onClick={async () => {
    await router.refresh();
    reset();
  }}
>
  다시 시도
</button>

"그럼 그냥 async/await" 붙이면 되겠네? <- 안된다. refresh 함수의 리턴값은 프로미스가 아니라 그냥 void다. 그럼 어떻게 해결해야 할까?

StartTransition

startTransition이라는 메서드를 사용해야 한다.

startTransition(() => {});

내부에는 콜백함수가 들어가는데, 콜백함수 내부에 "UI를 변경시키는 작업"을 일괄적으로(동시에) 처리해준다.

startTransition(() => {
  router.refresh();
  reset();
});

이렇게 사용하면 두 개가 동시에 처리가 되기 때문에 잘 작동할 것이다.

초록
초록

앱과 웹을 만들고, 직접 운영하며 기록합니다.

댓글

giscus로 동작하며 GitHub Discussions에 저장됩니다.

관련 글

Next.js 기초 - App RouterNext.jsweb

App Router (11) - 서버 액션 (Server Action)

2026.09.29·2분 읽기·조회 0
Next.js 기초 - App RouterNext.jsweb

App Router (9) - 스트리밍

2026.09.28·3분 읽기·조회 0
Next.js 기초 - App RouterNext.jsweb

App Router (8) - 라우트 세그먼트 옵션, 클라이언트 라우터 캐시

2026.09.26·1분 읽기·조회 0

목차

error.tsxerrorresetrouter.refreshStartTransition