react 16, Error handling with HOC

2018-10-31

리액트 16 에서는 LifeCycle에 많은 변화가 있었고 17에서는 더 많은 변화가 있을 것이라고 예고했다.

이번에 새로 등장한 componentDidCatch(error, info) 라이프사이클 메소드를 이용해 에러를 관리하는 방법을 살펴보자.

기본적인 사용법

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

  componentDidCatch(error, info) {
    this.setState({ hasError: true });
  }

  render() {
    if (this.state.hasError) return <h1>ERROR!</h1>;
    else return this.props.children;
  }
}
<BoundaryError>
    <Component1 />
</BoundaryError>

위의 코드를 살펴보면 componentDidCatch에서 에러를 잡아 setStatehasError값을 바꿔 에러 상태값을 관리하고
그 상태값에 따라 리턴을 달리해 에러시에는 에러 문구로 에러가 난 컴포넌트를 대신하게 된다.

이렇게 하면 에러가 발생함에 따라 리액트 페이지 전체가 먹통이 되는 현상을 방지 할 수 있다.

HOC와 함께 사용하기

HOC는 Higher-Order Components로 간단히 설명하면 컴포넌트를 감싸는 컴포넌트라고 할 수 있다.

HOC에 대한 자세한 설명은 생략하고 Error Handling을 하는데 어떻게 사용하는지를 살펴보겠다.

const withErrorBoundary = WrappedComponent =>
  class extends Component {
    state = {
      hasError: false
    };
    componentDidCatch(error) {
      this.setState({ hasError: true });
    }
    render() {
      if (this.state.hasError) return "Sorry...";
      else return <WrappedComponent />;
    }
  };

위와 같이 클래스를 만드는 함수로 withErrorBoundary를 작성했다.

const Component1WithErrorBoundary = withErrorBoundary(Component1);
const Component2WithErrorBoundary = withErrorBoundary(Component2);
const Component3WithErrorBoundary = withErrorBoundary(Component3);
render(){
    return (
    	<>
        	<Component1WithErrorBoundary />
    	    <Component2WithErrorBoundary />
	        <Component3WithErrorBoundary />
        </>
    )
}

이제 위와 같이 사용할 수 있는데 이렇게 되면 에러가 난 컴포넌트만 해당 컴포넌트가 아닌 'Sorry…' 문구가 출력되게 될 것이며, 에러로 인해 리액트 페이지 전체가 먹통이 되는 현상을 방지 할 수 있다.


Reference