xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

React Error Boundary All In One

React Error Boundary All In One

Error Boundary


class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  // 处理错误 fallback UI
  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }
  // 上报错误 log 记录
  componentDidCatch(error, info) {
    // Example "componentStack":
    //   in ComponentThatThrows (created by App)
    //   in ErrorBoundary (created by App)
    //   in div (created by App)
    //   in App
    logComponentStackToMyService(info.componentStack);
  }

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

    return this.props.children;
  }
}


https://reactjs.org/docs/error-boundaries.html


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;
  }  
}

componentDidCatch & `` + getDerivedStateFromError bug ??

https://codepen.io/gaearon/pen/wqvxGa?editors=0010

https://reactjs.org/docs/error-boundaries.html#live-demo

https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html

static getDerivedStateFromError()

https://reactjs.org/docs/react-component.html#static-getderivedstatefromerror

componentDidCatch()

componentDidCatch() is called during the “commit” phase, so side-effects are permitted.
It should be used for things like logging errors:

componentDidCatch() 在“提交”阶段被调用,所以副作用是允许的。
它应该用于记录错误之类的事情:

https://reactjs.org/docs/react-component.html#componentdidcatch

npm

import {ErrorBoundary} from 'react-error-boundary'

function ErrorFallback({error, resetErrorBoundary}) {
  return (
    <div role="alert">
      <p>Something went wrong:</p>
      <pre>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  )
}

const ui = (
  <ErrorBoundary
    FallbackComponent={ErrorFallback}
    onReset={() => {
      // reset the state of your app so the error doesn't happen again
    }}
  >
    <ComponentThatMayError />
  </ErrorBoundary>
)

https://www.npmjs.com/package/react-error-boundary

https://github.com/bvaughn/react-error-boundary

demos

image

static getDerivedStateFromError bug ???

https://codesandbox.io/p/sandbox/react-error-boundary-getderivedstatefromerror-bug-2e9dwj

static getDerivedStateFromError ok ✅

import * as React from "react";

type Props = {
  children: any;
};

type State = {
  hasError: boolean;
  [key: string]: any;
};
class ErrorBoundary extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error: any) {
    // Update state so the next render will show the fallback UI.
    console.log(`❌ error =`, error);
    return { hasError: true };
  }

  componentDidCatch(error: any, info: any) {
    // Example "componentStack":
    //   in ComponentThatThrows (created by App)
    //   in ErrorBoundary (created by App)
    //   in div (created by App)
    //   in App
    // console.log(info.componentStack);
    console.log(`❌ error, info =`, error, info);
  }

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

export default ErrorBoundary;

https://codesandbox.io/p/sandbox/react-error-boundary-53f4dq

React Component LifeCycle

https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

React Reconciliation

https://reactjs.org/docs/reconciliation.html

https://beta.reactjs.org/learn/preserving-and-resetting-state

React Diffing Algorithm / React 差异算法

https://reactjs.org/docs/reconciliation.html#the-diffing-algorithm

key 的作用

https://reactjs.org/docs/reconciliation.html#keys

React Fiber 架构

React 组件的渲染过程可分为两个大阶段:

  1. render 阶段
  2. commit 阶段

render:JSX => render function => VDOM
template 转换成 render 函数,生成虚拟 DOM

VDOM => reconcile => Fiber
虚拟DOM 树 => 在 idle 时间 schedule 调度(CPU 时间分片) => 转换成 Fiber 链表

render 阶段执行 VDOM 转 Fiber 的 reconcile
commit 阶段更新 DOM,执行 Effect 等副作用逻辑;

commit 阶段又可以分为 before mutationmutationlayout 3 个小阶段;

image

image

(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!

refs

https://meticulous.ai/blog/react-error-boundaries-complete-guide/

https://www.geeksforgeeks.org/reactjs-reconciliation/

https://www.loginradius.com/blog/engineering/reacts-reconciliation-algorithm/

https://juejin.cn/post/7203336895887114300



©xgqfrms 2012-2021

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2023-02-24 18:51  xgqfrms  阅读(86)  评论(2编辑  收藏  举报