React16의 Error Boundary 활용 방법

React16의 Unceaught Error를 위한 Error Boudary와 Error Boudary HOC(Higher Order Component) 제작

Unncaught Error 시 React 동작


React15: 오류가 발생하더라도 UI는 변경되지 않음

React16 이후: 어셈블리 트리 전체unmountAs of React 16, errors that were not caught by any error boundary will result in unmounting of the whole React component tree.

React16의 ErrorBoudary 대응


ErrorBoudary를 만들고componentDidCatch를 사용합니다


ErrorBoudary

  • 자손 어셈블리에서 오류가 발생하면 catch
  • 가능
  • componentDidCatch의function을 사용하여 발생하는 오류를 처리할 수 있음
  • 여러 ErrorBoudary
  • 사용 가능

    componentDidCatch(error, errorInfo)

  • 자바스크립트 같다catch
  • error: react error
  • errorInfo: 구성 요소의 오류가 발생한 곳은 이해하기 쉽다
  • The above error occurred in the <TodoItem> component:
        in TodoItem (created by TodoApp)
        in div (created by TodoList)
        in TodoList (created by TodoApp)
        in ErrorBoundary (created by TodoApp)
        in div (created by TodoApp)
        in TodoApp
    
    React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
    

    Code Demo jsfiddle

    class ErrorBoundary extends React.Component {
      constructor(props) {
        super(props);
        this.state = {error: null, errorInfo: null};
      }
    
      componentDidCatch(error, errorInfo) {
        // Catch errors in any components below and re-render with error message
        this.setState({error, errorInfo})
        // You can also log error messages to an error reporting service here
      }
    
      render() {
        if (this.state.errorInfo) {
          // Error path
          return (
            <div>
              <h2>Something went wrong.</h2>
              <details style={{whiteSpace: 'pre-wrap'}}>
                {this.state.error && this.state.error.toString()}
                <br />
                {this.state.errorInfo.componentStack}
              </details>
            </div>
          );
        }
        // Normally, just render children
        return this.props.children;
      }  
    }
    
    
    ErrorBoundary 사용
    <ErrorBoundary>
     <TodoList/>
     <AddTodo/>
    </ErrorBoundary>
    

    사용자 정의 오류 처리


    ProponError(발생한 오류를 처리하는 funtion) 및 ErrorComponent(Error message)입니다.
    const ErrorComponent = ({error, errorInfo}) => (
      <div>
        <h2>Something went wrong.</h2>
        <details style={{whiteSpace: 'pre-wrap'}}>
          {error && error.toString()}
          <br />
          {errorInfo.componentStack}
        </details>
      </div>
    )
    
    const onError = (error, errorInfo) => (
      console.error(error, errorInfo)
    )
    
    <ErrorBoundary ErrorComponent={ErrorComponent} onError={onError}>
    ...
    </ErrorBoundary>
    

    ErrorBoudary를 Higher Order Component로 활용


    만약 모든 그룹이 ErrorBoudary를 사용한다면 때때로 매우 번거로울 수 있다.
    <ErrorBoundary>
     <TodoList>
      <ErrorBoundary>
        <TodoItem/>
      </ErrorBoundary>
      <ErrorBoundary>
        <TodoItem/>
      </ErrorBoundary>
     </TodoList>
     <AddTodo/>
    </ErrorBoundary>
    
    
    -> Higher Order Component 활용
    class ErrorBoundary extends React.Component {
    ...
    }
    
    function ErrorBoundaryHOC(Component){
        return class ErrorBoundaryComponent extends React.Component {
        render(){
          return (
            <ErrorBoundary>
              <Component {...this.props} />
            </ErrorBoundary>
          )
        }
      }
    }
    
    상술한 문제는 해결할 수 있다.또한 HOC를 사용하면 뷰 측면에 변경 사항이 없으며 ErrorBoundary를 적용할 수 있습니다.
    const TodoItemHOC = ErrorBoundaryHOCTodoItem
    //Viewを変更したくない
    //const TodoItem = ErrorBoundaryHOC(require('./TodoItem')
    
    <ErrorBoundary>
     <TodoList>
      <TodoItemHOC/>
      <TodoItemHOC/>
     </TodoList>
     <AddTodo/>
    </ErrorBoundary>
    
    

    당신 이 졌습니다


    React15처럼 UI를 변경하고 싶지 않음


    위에서 말한 바와 같이 만약에 오류가 발생하면 과장ErrorComponent이지만 나는 아마 자주 그것을 하고 싶지 않을 거라고 생각한다.User에게도 오류 메시지를 보고 싶지 않습니다.
    이를 실현하기 위해 간단한 오류가 발생했을 때, 렌더링 ErrorComponent 을 하지 않고,children만 렌더링합니다.
      render() {
        // Normally, just render children
        return this.props.children;
      }  
    
    

    오류 처리 기본적으로 모든 프로젝트 사용하기


    ErrorBoundary 작성
    ErrorBoundary.defaults = {
      ErrorComponent: null,
      onError: null
    }
    
    ErrorBoundary.setOptions = function(opt) {
      merge(ErrorBoundary.defaults, opt)
    }
    
    class ErrorBoundary extends React.Component {
       constructor(props) {
        super(props);
        const {onError, ErrorComponent} = this.props
        //propsが優先される
        const opt = merge({}, ErrorBoundary.defaults, {onError, ErrorComponent}}
        this.state = merge({error: null, errorInfo: null}, opt}
      }
    }
    
    ErrorBoundary 활용
    import ErrorBoundary from './ErrorBoundary'
    
    ErrorBoundary.setOptions({onError, ErrorComponent})
    

    좋은 웹페이지 즐겨찾기