Edited at

React 16でError Boundaryが導入された

More than 1 year has passed since last update.


このスライドについて


  • 弊社(株式会社チームスピリット)のフロントエンドランチネタとして用意したスライドです


  • ブログ にはもうちょっと詳しく書きました



この話

SS 2017-08-02 5.03.45.png

https://facebook.github.io/react/blog/2017/07/26/error-handling-in-react-16.html



これまで


  • コンポーネント内で発生したランタイムエラーをうまくハンドリングする方法が提供されていなかった

  • エラーが発生すると React の内部状態(internal state)も壊れ、結果的によくわからないエラーがコンソールに表示される要因になっていた

(※internal state については訳がおかしいかも)


In the past, JavaScript errors inside components used to corrupt React’s internal state and cause it to emit cryptic errors on next renders.




Error Boundary


class ErrorBoundary extends React.Component {

constructor(props) {
super(props);
this.state = { hasError: false };
}

/********* これが新しく追加 ************/
componentDidCatch(error, info) {
// Display fallback UI
this.setState({ hasError: true });
// You can also log the error to an error reporting service
logErrorToMyService(error, info);
}

render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}


通常のコンポーネントと同じように使う

<ErrorBoundary>

<AddTodo />
<VisibleTodoList />
<FilterLinkList />
</ErrorBoundary>



Demo



Error Boundary


  • 子孫コンポーネントツリーで発生したエラーを catch するためのコンポーネント


  • componentDidCatch というライフサイクルメソッドが追加され、子孫コンポーネントツリーで発生したエラーはそこでハンドリングできるように

  • コンポーネントツリー内にいくつでも置ける


    • 独立して動作するUIパーツ単位で Boundary を設けたり





componentDidCatch(error, info)



  • error: Error オブジェクト


  • info: info.componentStack で Component Stack Trace が取れる


    • コンポーネントのどこで発生したエラーか?が追いやすい



in BuggyCounter (created by App)

in ErrorBoundary (created by App)
in div (created by App)
in App



Uncaught Error時の挙動の変更


  • React 15 まではエラーが発生しても UI はそのまま残る(Demo

  • React 16 以降、Uncaught Exception が発生すると コンポーネントツリーが全部 unmount される(非表示になる)Demo



所感


  • Error Boundary の導入によってエラーハンドリング(特に外部へのエラーログ送信など)はやりやすくなった

  • Uncaught Error 時の仕様変更があるので、最低限「ルートに1個 Boundary を追加する」ぐらいはやっておかないといけなさそう