iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 16
1
Modern Web

30天React從入門到入坑系列 第 16

DAY16:React Error Boundaries

  • 分享至 

  • twitterImage
  •  

在react尋找錯誤處理,看到一個有趣的名詞叫Error Boundaries,好像沒有中文名詞但大致的意思是錯誤的邊界。當發生錯誤時限縮錯誤範圍,不會影響到其它UI原件仍可繼續操作。而 Error Boundaries 也可定義成元件形成一個新的lifecycle,稱為 componentDidCatch(error, info) ,這比以往傳統的 try{}catch{} 方便操作。以下簡單修改官方範例,讓大家體會一下Error Boundariestry{}catch{} ,但在handle發生錯誤還是需要靠 try{}catch{} 才有辦法進行捕捉。

src/ErrorBoundary.js

import React, { Component } from 'react';

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: error,
      errorInfo: 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;
  }
}

export default ErrorBoundary;
src/ErrorCounter.js

import React, { Component } from 'react';

class ErrorCounter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { counter: 0, error: null };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(({counter}) => ({
      counter: counter + 1
    }),
    function(){
      console.log(this.state.counter)
      try {
        if(this.props.action === "handleClick" && this.state.counter === 3) {
          throw new Error('handleClick error!!');
        }
      } catch (error) {
        this.setState({ error: error });
      }
    });
  }

  render() {
    if (this.state.counter === 5) {
      throw new Error('error!!');
    } else if(this.state.error !== null) {
      return <h1>{this.state.error}</h1>;
    }
    return <h1 onClick={this.handleClick}>{this.state.counter}</h1>;
  }
}

export default ErrorCounter;
src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import ErrorBoundary from './ErrorBoundary';
import ErrorCounter from './ErrorCounter';
import registerServiceWorker from './registerServiceWorker';

const App = () => (
  <div>
    <ErrorBoundary>
      <ErrorCounter />
    </ErrorBoundary>
    <ErrorBoundary>
      <ErrorCounter action={"handleClick"} />
    </ErrorBoundary>
  </div>
)

ReactDOM.render(
  <App /> ,
  document.getElementById('root'));
registerServiceWorker();

輸出畫面
https://ithelp.ithome.com.tw/upload/images/20180103/20107317FAYuGrqBFG.png

此error畫面開發模式才會顯示
https://ithelp.ithome.com.tw/upload/images/20180103/201073178paxEsWbX7.png

ErrorBoundary補捉畫面
https://ithelp.ithome.com.tw/upload/images/20180103/20107317Au6MgpZYoh.png

try{}catch{}補捉畫面
https://ithelp.ithome.com.tw/upload/images/20180103/20107317sBqsDn1VyD.png

參考資料:Error Boundaries
https://reactjs.org/docs/error-boundaries.html


上一篇
DAY15:React prop-types 型別檢查
下一篇
DAY17:React state 同步,非同步??
系列文
30天React從入門到入坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言