React - 例外処理
例外処理
例外処理とは
- プログラムの実行中にエラーが発生した際、エラーをそのまま実行させずにエラーに対応すること
必要性
- 例外処理を通じて、プログラムの異常終了を防ぐことができる- プログラム開発中に問題が発生した場合、その解決に必要な時間を短縮できる
種類
エラー境界
特徴
- React 16から導入された新しい例外処理方式 - 宣言的にエラーを管理することを目的としている - 子コンポーネントで発生したエラーを処理できるコンポーネント - 子コンポーネントでエラーが発生した場合、親コンポーネントでエラーを記録する
- エラー発生時、エラーが発生したコンポーネントの代わりにフォールバックUI[^1]を表示する - render/useEffectで発生したエラーを処理可能 - イベントハンドラーやフックでは使用不可 - ただし、useErrorBoundaryを利用することで、Error Boundaryが処理できないエラーを渡すことが可能
メソッド
- static getDerivedStateFromError(): エラーに対する応答として状態を更新し、ユーザーにエラーメッセージを表示する機能として使用される- componentDidCatch(): サービスに関するエラーを記録する- catch{}文と同様に動作するが、コンポーネント内でのみ機能する
使用不可能な状況
- イベントハンドラー- 非同期コード- サーバーサイドレンダリング- エラー境界自体で発生するエラー
使用方法
react //定義するサブクラスclass ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = {hasError: false}; }
static getDerivedStateFromError(error) { //次のレンダリングでフォールバックUIが表示されるよう状態を更新 return {hasError : true}; }
componentDidCatch(error, errorInfo){ // エラー報告サービスにエラーを記録可能 logErrorToMyService(error, errorInfo);}
render() { //フォールバックUIをカスタマイズして、レンダリング可能にする return <> フォールバックUIの構成 </> } }
//メインコンポーネント
- エラー境界を使用するには、上記のコードのようにサブクラスにエラー境界を定義する必要がある- その後、定義したサブクラスでラップして使用可能
投げる
- 意図的に例外を発生させ、例外を処理させる役割を持つ
使用方法
サンプルコード
reactexport default function App() { const obj = undefined; const errorEvent = () => { try { throw new Error("例外が発生しました!"); } catch (error) { console.log(error); } } return( <> </> ) }
---------------------------------------------------//出力 "Error: 例外が発生しました"~~~
try-catch
使用方法
react try{ //実行するコード } catch(例外変数名) { //例外処理コード } finally { //オプション //終了後に実行するコード }
試す
- 実行するコード
キャッチ
- tryブロックは例外が発生した場合に処理する役割を持つ- エラーの種類に応じて無視/個別処理が可能である
ついに
- tryブロックが終了すると実行される部分 -tryブロックに関係なく、実行が終了すると必ず実行される
サンプルコード
reactexport default function App() { const obj = undefined; const errorEvent = () => { try { console.log(obj.name) } catch (error) { console.log('エラー発生 : ' + error); } finally { console.log('実行完了'); } } } return( <> </> ) }
//出力 "エラー発生 : TypeError: 未定義のプロパティを読み取れません ('name' の読み取り) " "実行完了"
##### Promiseにおけるtry-catch例外処理
react try { const response = await fetch('address');} catch(error) { console.log(error);}
- Promiseオブジェクトの場合、上記のコードのようにawaitを使用しない場合、catchで例外を処理できない
<br><br><br><br><br><br><br><br><br><br><br>
---
参考資料
- [エラー境界の扱い方(ErrorBoundary + react-error-boundary)](https://velog.io/@shyunju7/ERROR-BOUNDARY-%EB%8B%A4%EB%A3%A8%EA%B8%B0ErrorBoundary-react-error-boundary)
- [エラー境界(Error Boundaries)](https://ko.legacy.reactjs.org/docs/error-boundaries.html)
- [[JS/React] 後から整理する例外処理方式の一つであるtry/catch/finally](https://velog.io/@double29/JSReact-%EB%92%A4%EB%8A%A6%EA%B2%8C-%EC%A0%95%EB%A6%AC%ED%95%98%EB%8A%94- 例外処理の基礎と応用-trycatchfinally)
<br><br><br><br><br><br><br><br><br><br><br>
[^1]: 補助UIとして、メインUIが動作しない場合に代替機能を提供するUIである[^2]: [Promise]({{ site.baseurl }}/posts/비동기와-동기화)に関する内容はリンクを参照のこと