본문 바로가기
Express, Next.js/Next.js, React

[React] Suspense, Error boundary 란?

by 방배킹 2024. 5. 8.

Suspense

 

Suspense란 자식 컴포넌트가 로딩이 끝날때 까지 fallback을 보여주는 컴포넌트라고한다.

 

 

SomeComponent가 로딩이 끝날때까지 fallback에 해당하는 Loading 컴포넌트를 보여준다.

SomeComponent의 비동기 작업이 처리 되는 동안 fallback에 할당된 Loading 컴포넌트가 랜더링되는것이다. 그리고 해당 비동기 작업이 완료가 되면 다시 랜더링을 해서 SomeComponent를 랜더링해준다.

 

즉, Suspense 컴포넌트는 비동기 작업을 진행하는 자식 컴포넌트가 비동기 작업을 진행하는동안 fallback에 할당된 컴포넌트를 랜더링하고, 자식 컴포넌트의 비동기 작업이 완료되면 자식컴포넌트를 랜더링해준다.

 

만약 Suspense를 사용하지 않고 비동기 처리의 로딩을 구현한다면 어떻게 작성해야 할까?

 

useState와 useEffect를 사용해서 데이터가 로드 되었는지 여부를 확인한후 데이터가 로드되면 컴포넌트를 랜더링 하는 방식으로 사용해야한다.

function UserInfo(){
    const [user,setUser] = useState(null);
    
    useEffect{ ()=>{
    	fetchUser().then(u => setUser(u));
    },[]};
    
    if(user===null){
    	return(<h2>Loading User...</h2>);
    }
    return(
    	<div>
            <h1>{user.name}</h1>
        </div>
    )
}

 

비동기 처리가 진행중이라서 user가 null인 경우 Loading User...를 출력하고 fetch가 완료되면 setUser를 통해 state 값을 변화 시키고 다시 랜더링을 진행하고 이때 user가 null이 아니므로 user 정보가 출력된다.

Error Boundary

리엑트에서 화면을 렌더링을 할때 에러가 발생하면 리엑트 어플리케이션은 중지된다.

에러가 발생해서 어플리케이션이 중단되는것을 방지 하기 위해서 Error Boundary를 사용한다.

 

기본적으로 error boundary는 getDerivedStateFromError() 와 componentDidCatch() 를 정의한 클래스형 컴포넌트를 만들어서 사용한다.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // 다음 렌더링에서 폴백 UI가 보이도록 상태를 업데이트 합니다.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // 에러 리포팅 서비스에 에러를 기록할 수도 있습니다.
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // 폴백 UI를 커스텀하여 렌더링할 수 있습니다.
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

 

하지만 위 코드 처럼 error boundary는 클래스형 컴포넌트로 직접 구현을 해서 사용해야한다.

 

react-error-boundary를 사용하면 쉽게 error 처리를 할 수 있다.

 

react-error-boundary

https://www.npmjs.com/package/react-error-boundary

 

react-error-boundary

Simple reusable React error boundary component. Latest version: 4.0.13, last published: 2 months ago. Start using react-error-boundary in your project by running `npm i react-error-boundary`. There are 1160 other projects in the npm registry using react-er

www.npmjs.com

 

# npm
npm install react-error-boundary

 

react-error-boundary 패키지를 설치해준다.

 

"use client";

import { ErrorBoundary } from "react-error-boundary";

<ErrorBoundary fallback={<div>Something went wrong</div>}>
  <ExampleApplication />
</ErrorBoundary>

 

예시 코드는 위와 같다. Suspense와 사용 방법이 매우 유사하다. 자식 컴포넌트에서 에러가 발생하면 fallback에 있는 내용이 출력된다.

 

항상 같은 에러 처리가 아닌 에러메시지를 기반으로 화면을 렌더링 하고 싶은 경우에는 어떻게 해야할까?

 

ErrorBoundaryd의 fallbackRender를 사용하면 된다.

"use client";

import { ErrorBoundary } from "react-error-boundary";

function fallbackRender({ error, resetErrorBoundary }) {
  // Call resetErrorBoundary() to reset the error boundary and retry the render.

  return (
    <div role="alert">
      <p>Something went wrong:</p>
      <pre style={{ color: "red" }}>{error.message}</pre>
    </div>
  );
}

<ErrorBoundary
  fallbackRender={fallbackRender}
  onReset={(details) => {
    // Reset the state of your app so the error does not happen again
  }}
>
  <ExampleApplication />
</ErrorBoundary>;

 

로깅 등 더 자세한 내용은 공식문서를 참고하자

 

 

 

 

댓글