繁体   English   中英

反应 在DOM中崩溃后不显示错误信息

[英]React. Error info does not display after crash in the DOM

我进行了一个简单的测试,以捕获MyComponent组件中的错误,但是崩溃后,错误信息未显示在DOM中,而是在下面的代码中进行了描述。 在控制台中,它显示正常。

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import './index.css';

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

  handleClick = () => {
    this.setState({ counter: this.state.counter + 1 })
  }

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

  }

  render() {
    if (this.state.counter > 5) {
      throw new Error('Ooops!');
      return(
        <React.Fragment> // this is were Error must displayed 
        <div>{this.state.error.toString()}</div>
        <div>{this.state.errorInfo.componentStack}</div>
        </React.Fragment>
      );
    }
    return <div style={{cursor: 'pointer'}} onClick={this.handleClick}>Click Me: {this.state.counter}</div>
  }
}

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

////错误登录控制台:

    Uncaught Error: Ooops!
    at MyComponent.render (index.js:30)
    at finishClassComponent (react-dom.development.js:7873)
    at updateClassComponent (react-dom.development.js:7850)
    at beginWork (react-dom.development.js:8225)
    at performUnitOfWork (react-dom.development.js:10224)
    at workLoop (react-dom.development.js:10288)
    at HTMLUnknownElement.callCallback (react-dom.development.js:542)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:581)
    at invokeGuardedCallback (react-dom.development.js:438)
    at renderRoot (react-dom.development.js:10366)
    at performWorkOnRoot (react-dom.development.js:11014)
    at performWork (react-dom.development.js:10967)
    at batchedUpdates (react-dom.development.js:11086)
    at batchedUpdates (react-dom.development.js:2330)
    at dispatchEvent (react-dom.development.js:3421)
render @ index.js:30
finishClassComponent @ react-dom.development.js:7873
updateClassComponent @ react-dom.development.js:7850
beginWork @ react-dom.development.js:8225
performUnitOfWork @ react-dom.development.js:10224
workLoop @ react-dom.development.js:10288
callCallback @ react-dom.development.js:542
invokeGuardedCallbackDev @ react-dom.development.js:581
invokeGuardedCallback @ react-dom.development.js:438
renderRoot @ react-dom.development.js:10366
performWorkOnRoot @ react-dom.development.js:11014
performWork @ react-dom.development.js:10967
batchedUpdates @ react-dom.development.js:11086
batchedUpdates @ react-dom.development.js:2330
dispatchEvent @ react-dom.development.js:3421
index.js:2178 The above error occurred in the <MyComponent> component:
    in MyComponent (at index.js:43)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit s to learn more about error boundaries.
__stack_frame_overlay_proxy_console__ @ index.js:2178
logCapturedError @ react-dom.development.js:9747
captureError @ react-dom.development.js:10540
renderRoot @ react-dom.development.js:10391
performWorkOnRoot @ react-dom.development.js:11014
performWork @ react-dom.development.js:10967
batchedUpdates @ react-dom.development.js:11086
batchedUpdates @ react-dom.development.js:2330
dispatchEvent @ react-dom.development.js:3421
index.js:30 Uncaught Error: Ooops!
    at MyComponent.render (index.js:30)
    at finishClassComponent (react-dom.development.js:7873)
    at updateClassComponent (react-dom.development.js:7850)
    at beginWork (react-dom.development.js:8225)
    at performUnitOfWork (react-dom.development.js:10224)
    at workLoop (react-dom.development.js:10288)
    at HTMLUnknownElement.callCallback (react-dom.development.js:542)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:581)
    at invokeGuardedCallback (react-dom.development.js:438)
    at renderRoot (react-dom.development.js:10366)
    at performWorkOnRoot (react-dom.development.js:11014)
    at performWork (react-dom.development.js:10967)
    at batchedUpdates (react-dom.development.js:11086)
    at batchedUpdates (react-dom.development.js:2330)
    at dispatchEvent (react-dom.development.js:3421)

////

之前抛出错误的HTML可能不会引发您的错误。 尝试这样:

render() {
  if (this.state.counter > 5) {
    throw new Error('Ooops!');
  }
  return (
    <div>
    <div style={{cursor: 'pointer'}} onClick={this.handleClick}>Click Me: {this.state.counter}</div>
      { this.state.error &&
        <React.Fragment>
          <div>{this.state.error.toString()}</div>
          <div>{this.state.errorInfo.componentStack}</div>
        </React.Fragment>
      }
    </div>
  );
}

我认为这段代码行不通,因为当您引发错误时,该函数中的Javascript执行将停止:

render() {
  if (this.state.counter > 5) {
    throw new Error('Ooops!');

    // HERE, after the Error, the exution is stopped, and all the code below is ignored.

    return(
      <React.Fragment> // this is were Error must displayed 
        <div>{this.state.error.toString()}</div>
        <div>{this.state.errorInfo.componentStack}</div>
      </React.Fragment>
    );
  }
  return <div style={{cursor: 'pointer'}} onClick={this.handleClick}>Click Me: {this.state.counter}</div>
}

您可以做的是在引发错误时使用try/catch块,或者仅在存在错误信息时呈现错误信息,例如:

render() {
  if (this.state.error) {
    return(
      <React.Fragment> // this is were Error must displayed 
        <div>{this.state.error.toString()}</div>
        <div>{this.state.errorInfo.componentStack}</div>
      </React.Fragment>
    );
  }
  if (this.state.counter > 5) {
    throw new Error('Ooops!');
  }
  return <div style={{cursor: 'pointer'}} onClick={this.handleClick}>Click Me: {this.state.counter}</div>
}

这就是您可以做的-在错误检查程序MyComponent组件中包含可执行Component组件。 它将起作用:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { 
      error: null,
      errorInfo: null
    };
  }

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

  render() {
    if (this.state.errorInfo) {
      return(
        <React.Fragment>
          <div>{this.state.error && this.state.error.toString()}</div>
          <div>{this.state.errorInfo.componentStack}</div>
        </React.Fragment>
      );
    }   
    return this.props.children;
  }
}

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

  handleClick = () => {
    this.setState({ counter: this.state.counter + 1 })
  }

  render() {
    if (this.state.counter > 5) {
      throw new Error('Ooops!');
    }
    return <div style={{cursor: 'pointer'}} onClick={this.handleClick}>Click Me: {this.state.counter}</div>
  }
}

ReactDOM.render(
  <MyComponent>
    <Component />
  </MyComponent>,
  document.getElementById('root')
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM