본문 바로가기
SeSAC

[SeSAC] React 학습 정리(4) - LifeCycle(2)

by hotdog7778 2023. 10. 14.

함수형 컴포넌트에서 발생하는 에러처리 - 에러 바운더리

 

1. 함수형 컴포넌트에서 발생하는 에러처리 방법

🍞 함수형 컴포넌트에서 클래스형 컴포넌트의 에러처리 메서드 또는 에러바운더리를 대체하는 Hook은 현재는 없다.

 

 - 에러처리 메서드를 사용 하는 클래스형 컴포넌트(에러바운더리)의 자식 컴포넌트에 위치 시킨다.

 - js 내에서 try-catch 사용한다.

 

 

2. 에러 바운더리 : 

자식 컴포넌트 트리 내의 자바스크립트 오류를 감지하고, 해당 오류를 기록하며, 충돌이 발생한 컴포넌트 트리를 대신하여 대체 UI를 표시하는 React 컴포넌트

 

✓ 에러 바운더리는 클래스형 컴포넌트여야 한다. (현재는 함수형 컴포넌트로 에러바운더리를 만드는것은 지원되지 않는다.)

✓ 에러 바운더리 내에 getDerivedStateFromError() 또는 componentDidCatch() 메서드 를 필수로 사용해야 한다.

에러 바운더리는 트리 내에서 자신보다 하위에 존재하는 컴포넌트에 대한 오류만을 감지한다. 즉, 에러 바운더리는 자기 자신에 대한 오류를 감지할 수 없음

 

에러 바운더리는 랜더링시 의도치않은 에러 발생시 사용자에게 보여줄 화면을 정해놓을 수 있어서 사용자 환경 개선에 도움

 에러 바운더리는 개발자가 미리 예상하고 대비할 수 없는 오류를 감지하고 처리하는데 사용되어야 하며, 코드 흐름이나 프로그램의 로직을 변경하는 데는 사용하지 말 것. 이러한 규칙을 따르면 코드가 더 예측 가능하고 유지 보수에 장점을 살릴 수 있다. 예를 들면 네트워크 연결이 끊어진다거나, 데이터를 불러오는 도중 서버에 문제가 생긴다거나, 파일을 찾을 수 없다거나 하는 경우

 

 

에러 바운더리 작성 방법 : 에러바운더리로 자식 컴포넌트를 감싸는 방법으로 사용

// 아래 처럼 에러바운더리로 감싸면 된다.

<ErrorBoundary> ..부모 컴포넌트(클래스형)[에러바운더리]

  <MyComponent /> ..자식 컴포넌트(함수형)

</ErrorBoundary> 

<ExamCompenent /> 

// ExamCompenent 컴포넌트는 에러바운더리 내에 위치하지 않기때문에 에러발생시 에러바운더리에서 처리하지않음

 

ErrorBoundary.js 

import React, { Component } from 'react';

export default class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    // 에러가 발생하지 않았다는 state 초기값 설정
    this.state = { hasError: false };
  }

  // 이 메서드는 매개변수로 오류를 전달받고, 갱신된 state 값을 반드시 반환해야 한다.
  // 자식 컴포넌트에서 오류가 발생하면 이 메서드가 호출된다.
  static getDerivedStateFromError(error) {
    // state를 갱신하여 다음 렌더링에서 대체 UI를 표시합니다.
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      // 별도로 작성한 대체 UI를 렌더링할 수도 있습니다.
      return <h1>Something went wrong.</h1>;
    }

    // this.props.children은 React 컴포넌트가 부모 컴포넌트로부터 전달받은 자식 엘리먼트(또는 컴포넌트)를 나타냅니다.
    // 따라서 아래 코드는 Error Boundary 컴포넌트가 자식 컴포넌트를 그대로 렌더링하는 것을 의미한다.
    return this.props.children;
  }
}

 

MyComponent.js

import React, { useState } from 'react';

export default function MyComponent() {
  // const [error, setError] = useState(null);

  const myFunc = () => {
    // 에러 발생 코드
    throw new Error('에러 발생!');
  };

  // 컴포넌트 내에서 에러 발생 코드가 있는 함수 실행
  myFunc();

  return (
    <div>
      <h1>함수형 컴포넌트 에러 처리</h1>
    </div>
  );
}

 

결과

 

ErrorBoundary.js 에서 에러가 확인된 후 처리되면 <h1>Something went wrong.</h1>  가 렌더된다.

정상일 경우 MyComponent.js 의 <h1>함수형 컴포넌트 에러 처리</h1> 가 렌더된다.

 

 

3. 에러 바운더리를 사용하더라도 모든 상황에서 오류를 처리할 수 없다.

예시)비동기 작업의 오류, 이벤트 핸들러 내의 오류

 

 

 

 

 

 

참고

https://ko.legacy.reactjs.org/docs/react-component.html

https://ko.legacy.reactjs.org/docs/error-boundaries.html

https://wikidocs.net/197630