Dev study 정리

componentDidCatch() 함수 확인

2dubbing 2018. 8. 30. 21:20

 

 

React 릴리즈 버전이 16.4.x 버전까지 올랐다는 걸 React 공식페이지나 여러 기술블로그를 통해 알고 있었다.

 

하지만, 변경 된 사항들에 대해 글을 읽기만 했을 뿐 간단한 예를 만들어서 해보지는 않았다.

 

최근 이직 준비로 인한 시간이 생겨 변경 된 사항들을 직접 해보고 있다.

 

 

오늘은 React v16.0 에 새로 추가 된 componentDidCatch() 함수에 대해 알아보고 

 

이 함수를 어떠한 경우 사용하면 좋을지에 대해 알아보려한다.

 

 

 

React 프로젝트는 수 많은 UI 컴포넌트 트리로 구성되어 있다. 

 

화면 렌더링이 시작되면 수 많은 UI 컴포넌트 들이 각자 역할에 맞게 수행되

 

가장 마지막에 위치한 컴포넌트의 역할이 끝나면 페이지 렌더링이 완료된다.

 

만약 렌더링 도중 어떠한 컴포넌트에서 런타임 에러가 발생하면 에러가 발생한 컴포넌트는 

 

UI 렌더링이 되지 않는다. 여기에서 끝나지 않고  에러는 꼬리에 꼬리를 물고 다른 컴포넌트들에 영향을 미치게 된다.

 

결국에는 해당 화면 렌더링이 정상적으로 수행되지 않는 상황에 도달하게 된다.

 

 

이러한 문제를 막고 에러 처리를 개선하기 위해 Facebook은 React v16.0 에

 

componentDidCatch() 함수를 도입했다. 

 

 

 

함수에 대한 자세한 정보는 아래 링크에서 확인가능 하다.

 

<React 공식페이지 링크: https://reactjs.org/blog/2017/09/26/react-v16.0.html#better-error-handling>

 

 

 

 

componentDidCatch(error, errorInfo) 함수는 컴포넌트가 렌더링 되는 도중 런타임 에러가 발생하면 호출되는 콜백함수다.

 

함수의 첫번째 인자는 에러 메시지, 두번째 인자는 발생한 에러에 대한 상세정보 객체다.

 

 

이 함수를 모든 컴포넌트에 선언해서 사용하는게 아닌, 별도로 컴포넌트화 하여 에러가 발생할 소지가 있는 컴포넌트의 부모 컴포넌트로 하여

 

사용하면 효율적인 사용이 가능하다.

 

 

 

 

 

componentDidCatch() 함수 동작방식을 알아보기 위해 간단한 예제를 만들었다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
import React from 'react';
 
const Toppick = (props) => {
  if (props.data.length > 10) {
    throw new Error("title error");
  }
  return (
    <h2>{props.data}</h2>
  );
}
 
export default Toppick;
 
cs

 

 

 

Toppick 컴포넌트는 별도의 상태값을 가지지 않고 상위 컴포넌트로 부터 전달받은 데이터를 렌더링만 하는 stateless component 다.

 

componentDidCatch() 함수 동작을 확인하기 위해 에러발생 조건 로직(4 ~ 6 라인)을 추가했다.   

 

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import React, { Component } from 'react';
 
class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      errorInfo: null
    };
  }
 
  componentDidCatch(error, errorInfo) {
    this.setState({
      error: error,
      errorInfo: errorInfo
    });
  }
 
  render() {
    if (this.state.error) {
      return (
        <div className="ErrorBoundary">
          <section>
            <h2>React Component Error!</h2>
            <aside>
              <p>{this.state.error && this.state.error.toString()}</p>
            </aside>
            <aside>
              <p>
                <detail className="ErrorBoundary-error-detail">{this.state.errorInfo.componentStack}</detail>
              </p>
            </aside>
          </section>
        </div>
      );
    }
    
    return this.props.children;
  }
}
 
export default ErrorBoundary;
cs

 

ErrorBoundary 컴포넌트는 throw 된 에러들을 캐치하여 에러정보를 화면에 제공하기  컴포넌트다.

 

 

 

 

 

 

 

다음과 같이 Toppick 컴포넌트를 ErrorBoundary 컴포넌트의 자식 컴포넌트가 되도록 구성했다.

 

Toppick 컴포넌트가 렌더링한 내용을 보여주다가 Toppick 컴포넌트에서 에러가 발생하면 

 

ErrorBoundary 컴포넌트의 componentDidCatch() 에서 throw 된 에러를 받고, 에러정보를 화면에 보여주게 된다.

 

 

 

 

  

 

 

<에러가 발생하지 않았을 경우>

 

 

 

 

 

<에러가 발생한 경우>