ワイのメモ帳なんやで...

主にWebプログラミングのお話をします。

React componentDidCatchでcatch出来ない?

タイトル通り

React16から追加された componentDidCatch メソッドがコールされなかったの。

公式と同じErrorBoundaryのComponentを定義したのにそんなことあるぅ?

先に言っておくと公式キチンと読んでいないだけです。

ErrorBoundaryのComponent
import React from "react";

export default class ErrorBoundary extends React.Component {
  state = { hasError: false };

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

  render() {
    return this.state.hasError ? (
      <h1>エラーキャッチしたんじゃ</h1>
    ) : (
      this.props.children
    );
  }
}
 
throwするComponent
import React, { Component } from "react";

class MethodThrow extends Component {
  throwError() {
    throw new Error("error!!!");
  }

  render() {
    return (
      <button type="button" onClick={this.throwError}>
        method throw
      </button>
    );
  }
}

export default MethodThrow;

ボタン押したらthrowが走って「エラーキャッチしたんじゃ」が表示され

ないんですよ。マスオさんもびっくり。

 

正解はこちら
import React, { Component } from "react";

class LifecycleThrow extends Component {
  constructor(props) {
    super(props);
    this.state = { error: false };
    this.throwError = this.throwError.bind(this);
  }

  throwError() {
    this.setState({ error: true });
  }

  render() {
    if (this.state.error) {
      throw new Error("error!");
    }
    return (
      <button type="button" onClick={this.throwError}>
        lifecycle throw
      </button>
    );
  }
}

export default LifecycleThrow;

throwをReactのライフサイクルメソッド内で発火するように変更。

これで無事エラーキャッチしたんじゃ。

 

公式を見ると

Note

Error boundaries do not catch errors for:

  • Event handlers (learn more)
  • Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks)
  • Server side rendering
  • Errors thrown in the error boundary itself (rather than its children)

 

Error boundaries do not catch errors for:

Event handlers

Event handlers

Event handlers

あっはーい。

DOMへのイベントハンドラのバインドを終えたら次のState更新があるまでComponentの役目は終わっているもんね。。。

 

ということでSandbox。