React错误边界与React不兼容。

26

这是我的错误边界文件 -

class ErrorHandling extends Component {
    state = { hasError: false }

    componentDidCatch() {
        this.setState({ hasError: true })
    }

    render() {
        // debugger
        if (this.state.hasError) {
            return <div>Error in Component</div>
        }
        return this.props.children
    }
}

另一个文件是 -

import React, { Component } from 'react';

// Intentionally I have added syntax error below 'd'

function Intermediate(props) {
    return <h1>hi</h1>;d
}
export default Intermediate

并且在我的 App.js 文件中

<ErrorHandling>
  <Intermediate />
</ErrorHandling>

这导致应用程序崩溃,而不捕获错误。以下是在浏览器屏幕上看到的错误:

在此输入图像描述

更详细的版本在此处- https://codepen.io/meghana1991/pen/abojydj?editors=0010

当我在本地使用多个文件中列出的相同代码时,它无法正常工作。

2个回答

42

无法捕获编译时错误,Error Boundaries 主要用于 UI 运行时错误。

请参考 Compile time vs run time errors

此外,您需要使用 getDerivedStateFromError 来在后备 UI 上添加额外的渲染内容:

class ErrorBoundary extends React.Component {
  state = {
    hasError: false,
    error: { message: '', stack: '' },
    info: { componentStack: '' }
  };

  static getDerivedStateFromError = error => {
    return { hasError: true };
  };

  componentDidCatch = (error, info) => {
    this.setState({ error, info });
  };

  render() {
    const { hasError, error, info } = this.state;
    const { children } = this.props;

    return hasError ? <ErrorComponent/> : children;
  }
}

为检查你的 ErrorBoundary,需要从组件树中可达的部分抛出错误(但不能是下列情况)::

  • 事件处理函数
  • 异步代码(例如 setTimeout 或 requestAnimationFrame 回调函数)
  • 服务器端渲染
  • 在错误边界本身中抛出的错误(而不是它的子组件)
const ButtonComponent = () => {
  throw Error("error!");
  return <></>;
};

注意: 在开发环境中,除非您关闭或使用 X 按钮关闭它,否则始终会看到错误叠加。


完整示例:

const ErrorComponent = () => {
  return <h1>Something went wrong</h1>;
};

class ErrorBoundary extends React.Component {
  state = {
    hasError: false,
    error: { message: "", stack: "" },
    info: { componentStack: "" }
  };

  static getDerivedStateFromError = error => {
    return { hasError: true };
  };

  componentDidCatch = (error, info) => {
    this.setState({ error, info });
  };

  render() {
    const { hasError, error, info } = this.state;
    console.log(error, info);
    const { children } = this.props;

    return hasError ? <ErrorComponent /> : children;
  }
}

const ButtonComponent = () => {
  throw Error("error!");
  return <></>;
};

const App = () => {
  return (
    <ErrorBoundary>
      <ButtonComponent />
    </ErrorBoundary>
  );
};

Edit Error-Boundary Example


3
我已经尝试了,但不幸的是没有起作用。我仍然在我的应用屏幕上看到错误。 - M3ghana
34
在开发环境中,除非您关闭或使用“X”按钮关闭它,否则将始终看到错误覆盖层。 - Dennis Vash
已添加。请检查。 - M3ghana
我编辑了答案,这是编译时错误,你的应用程序甚至无法启动,你无法动态捕获它。 - Dennis Vash
4
@ShamseerAhammed更新了示例,你无法从像onClick这样的事件处理程序中捕获错误,感谢你发现了这个问题。 - Dennis Vash
显示剩余12条评论

3
事实是:在React文档示例中看到的美观回退界面只会在生产环境出现。因此,您需要运行create-react-app建议的命令(如果您使用它):
npm run build
# wait for it to finish
serve -s build

如果你在终端中看到了这个地址,请在浏览器中打开localhost:5000。这样React文档示例就可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接