React

ErrorBoundary

TypeScript
TypeScript
React
React
선언적으로 에러 상태를 처리하는 컴포넌트입니다.
react-error-boundary
ErrorBoundary
를 재정의하며, 컴포넌트 외부에서
ref.current.reset()
을 호출해 에러 상태를 리셋할 수 있습니다.

요구 사항

  • npm i react-error-boundary
  • React 19+ (React 19 미만에서는
    forwardRef
    ref
    전달해야 합니다)

구현

'use client';

import { type ComponentType, createElement, type ReactNode, type Ref, useImperativeHandle, useRef } from 'react';
import {
  type FallbackProps,
  ErrorBoundary as ReactErrorBoundary,
  type ErrorBoundaryProps as ReactErrorBoundaryProps,
} from 'react-error-boundary';

export type ErrorFallbackProps = Omit<FallbackProps, 'resetErrorBoundary'> & {
  reset: FallbackProps['resetErrorBoundary'];
};

export type ErrorBoundaryRef = {
  reset: ErrorFallbackProps['reset'];
};

export type ErrorBoundaryProps = Pick<ReactErrorBoundaryProps, 'onError' | 'onReset' | 'resetKeys' | 'children'> & {
  fallback?: ReactNode | ComponentType<ErrorFallbackProps>;
  ref?: Ref<ErrorBoundaryRef>;
};

export function ErrorBoundary({ fallback, ref, ...props }: ErrorBoundaryProps) {
  const resetRef = useRef<(() => void) | undefined>(undefined);

  useImperativeHandle(ref, () => ({
    reset: () => {
      if (resetRef.current) resetRef.current();
    },
  }));

  if (typeof fallback === 'function') {
    const fallbackRender: ReactErrorBoundaryProps['fallbackRender'] = ({ resetErrorBoundary: reset, ...props }) => {
      resetRef.current = reset;
      return createElement(fallback, { ...props, reset });
    };

    return (
      <ReactErrorBoundary
        fallbackRender={fallbackRender}
        {...props}
      />
    );
  }

  return (
    <ReactErrorBoundary
      fallback={fallback}
      {...props}
    />
  );
}

사용법

1. 기본 사용 —
fallback
을 ReactNode로 전달

<ErrorBoundary fallback={<ErrorFallback />}>
  <Component />
</ErrorBoundary>

2.
ref
로 외부에서 리셋

const ref = useRef<ErrorBoundaryRef>(null);

useEffect(() => {
  ref.current?.reset();
}, [...deps]);

<ErrorBoundary
  ref={ref}
  fallback={<ErrorFallback />}
>
  <Component />
</ErrorBoundary>;

3.
reset
콜백 호출 —
fallback
을 컴포넌트로 전달

<ErrorBoundary fallback={({ error, reset }) => <ErrorFallback onClick={() => reset()}>{error.message}</ErrorFallback>}>
  <SuspendedComponent />
</ErrorBoundary>

4.
resetKeys
를 변경해 리셋

const [resetKey, setResetKey] = useState('apple');

useEffect(() => {
  setResetKey('banana');
}, [...deps]);

<ErrorBoundary
  fallback={<ErrorFallback />}
  resetKeys={[resetKey]}
>
  <SuspendedComponent />
</ErrorBoundary>;

참조