웹사이트 검색

React에서 오류 경계를 사용하는 방법


소개

오류 경계는 렌더링 단계에서 발생하는 까다로운 오류를 포착하는 방법으로 React v16에 도입되었습니다. 과거에는 이로 인해 앱이 완전히 마운트 해제되었고 사용자는 빈 웹 페이지만 보게 되었을 것입니다. 이는 이상적이지 않습니다!

이 기사에서는 코드 스니펫과 대화형 데모를 통해 오류 경계에 대해 알아봅니다.

전제 조건

이 문서를 따라 하려면 다음이 필요합니다.

  • React에 대한 약간의 친숙함. React.js에서 코딩하는 방법 시리즈를 읽을 수 있습니다.

이 튜토리얼은 Node v16.4.2, npm v7.19.1 및 react v17.0.2에서 검증되었습니다.

오류 경계 없이 오류 발생

개발하는 동안 앱에서 예기치 않은 오류가 필연적으로 발생합니다. 존재하지 않는 개체의 깊게 중첩된 속성에 액세스하려고 시도하거나 때때로 제어할 수 없는 경우(예: 타사 API에 대한 실패한 HTTP 요청)일 수 있습니다.

아래 데모에서는 오류를 시뮬레이트하여 오류 경계 없이 일반적으로 발생하는 상황을 확인합니다.

import React from 'react';

class BuggyCounter extends React.Component {
  state = {
    counter: 0,
  };

  handleClick = () => {
    this.setState({
      counter: this.state.counter + 1,
    });
  };

  render() {
    if (this.state.counter === 5) {
      // Simulate an error!
      throw new Error('Simulated error.');
    }
    return (
      <div>
        <h1>{this.state.counter}</h1>
        <button onClick={this.handleClick}>+</button>
      </div>
    );
  }
}

export default BuggyCounter;

CodePen에서 라이브 코드 예제 @wle8300을 방문하십시오.

+(증분) 버튼을 클릭하고 5에서 어떻게 실패하는지 관찰합니다.

Output
Uncaught Error: Simulated error.

앱에 오류가 발생하면 구성 요소가 자체적으로 완전히 마운트 해제되고 사용자에게는 빈 HTML 페이지가 남습니다. 이로 인해 사용자는 혼란스러워하고 다음에 무엇을 해야할지 모를 수 있습니다.

오류 경계는 이러한 오류를 정상적으로 처리하는 방법을 제공합니다!

오류 경계가 있는 오류 발생

오류 경계란 정확히 무엇입니까? 당신이 생각하는 것과는 달리 새로운 구성 요소나 JavaScript 라이브러리가 아닙니다. React 구성 요소의 오류를 처리하는 전략과 비슷합니다.

특히 React 구성 요소에서 사용할 수 있는 두 가지 방법을 사용합니다.

import React from 'react';

class MyErrorBoundaryExample extends React.Component {
  state = {
    error: null,
  };

  static getDerivedStateFromError(error) {
    // Update state so next render shows fallback UI.
    return { error: error };
  }

  componentDidCatch(error, info) {
    // Log the error to an error reporting service
    logErrorToExampleService(error, info);
  }

  render() {
    if (this.state.error) {
      // You can render any custom fallback UI
      return <p>Something broke</p>;
    }
    return this.props.children;
  }
}

export default MyErrorBoundaryExample;

  • 정적 getDerivedStateFromError는 오류 경계가 상태를 업데이트할 기회를 허용하여 마지막 render()를 트리거하는 수명 주기 메서드입니다. 위의 코드 스니펫에서 상태는 손상된 구성 요소 대신 사람에게 친숙한 오류 메시지를 표시하는 데 사용됩니다(예: this.props.children).
  • componentDidCatch는 부작용(예: Crashlytics와 같은 도구에 오류 기록)을 트리거하도록 설계된 수명 주기 메서드입니다. info.componentStack에 액세스하여 버그 분류에 유용한 개발자 친화적인 스택 추적을 얻을 수 있습니다.

모든 React 구성 요소는 이러한 수명 주기 방법 중 하나 이상을 사용할 때 오류 경계로 간주됩니다.

모범 사례는 오류 처리 논리를 일반 구성 요소에 혼합하는 대신 오류 경계로 특수 제작된 구성 요소를 만드는 것이 좋습니다.

를 약간 수정한 다음 를 감싸서 오류를 잡아봅시다!

import React from 'react';

class MyErrorBoundary extends React.Component {
  state = {
    errorMessage: '',
  };

  static getDerivedStateFromError(error) {
    return { errorMessage: error.toString() };
  }

  componentDidCatch(error, info) {
    this.logErrorToServices(error.toString(), info.componentStack);
  }

  // A fake logging service.
  logErrorToServices = console.log;

  render() {
    if (this.state.errorMessage) {
      return <p>{this.state.errorMessage}</p>;
    }
    return this.props.children;
  }
}

export default MyErrorBoundary;

그리고 App.js:

import React from 'react';
import BuggyCounter from './BuggyCounter';
import MyErrorBoudnary from './MyErrorBoundary';

class App extends React.Component {
  refreshPage = () => {
    history.go(0);
  };

  render() {
    return (
      <div>
        <MyErrorBoundary>
          <BuggyCounter />
        </MyErrorBoundary>
        <hr />
        <button onClick={this.refreshPage}>Refresh Page</button>
      </div>
    );
  }
}

export default App;

BuggyCounter.js는 그대로 유지됩니다.

CodePen에서 라이브 코드 예제 @wle8300을 방문하십시오.

+(증가) 버튼을 다시 클릭해 보십시오. 5에 도달하면 정상적으로 충돌합니다. 또한 콘솔을 열어 스택 추적을 볼 수 있습니다!

완전히 충돌하는 대신 오류 경계를 사용하여 폴백 UI를 대체할 수 있습니다. 이는 사용자가 앱과 계속 상호 작용할 수 있도록 하는 동안 문제가 발생했다는 시각적 피드백을 사용자에게 제공합니다.

다른 곳으로 이동하거나 고객 서비스에 연락하여 상황을 해결하도록 선택할 수 있습니다! 불행한 사용자 경험을 보상하는 좋은 방법입니다.

오류 경계와 Try...Catch 비교

오류 경계는 실제로 try...catch 문과 직접적인 경쟁 관계에 있지 않습니다. 오류 경계는 React 구성 요소의 3개 위치에서 발생하는 오류를 가로채기 위해서만 설계되었습니다.

  • 렌더링 단계 동안
  • 수명주기 방식
  • 생성자에서

기본적으로... 컴포넌트의 React-y 부분입니다.

대위법으로 오류 경계가 오류를 포착할 수 없는 위치는 다음과 같습니다.

  • 이벤트 핸들러(예: onClick, onChange 등)
  • setTimeout 또는 requestAnimationFramecallbacks
  • 서버측 렌더링(SSR)
  • 오류 경계 자체(하위가 아닌)로 인해 발생하는 오류

따라서 오류 경계는 실제로 try...catch를 사용하는 방식에 영향을 미치지 않습니다. 둘 다 React에서 오류를 처리하기 위한 강력한 전략으로 필요합니다.

결론

이 기사에서는 오류 경계에 대해 배웠습니다.

참고: 오류 경계는 클래스 기반 React 구성 요소에서만 사용할 수 있습니다. 이 글을 쓰는 시점에는 현재 React Hooks를 사용하여 구현하는 방법이 없습니다.

React 버전 16부터 오류 경계를 사용할 수 있으므로 일반적으로 앱의 루트(예: App.js 파일)에서 하나 이상의 오류 경계를 사용하는 것이 좋습니다. 이렇게 하면 사용자에게 빈 HTML 페이지가 표시되지 않고 대신 멋진 대체 UI가 표시될 수 있습니다.

앞으로는 다른 폴백 UI를 사용하거나 타사 서비스에만 오류를 기록하는 여러 종류의 오류 경계를 사용할 수 있습니다.

자세한 내용은 공식 React 문서를 확인하세요!