使用ErrorBoundary组件在同一页面上反应JS shwo错误

时间:2018-09-17 01:46:22

标签: reactjs react-native error-handling react-redux react-router

我们已经实现了ErrorBoundary Component方法,以支持我们网站的常规错误处理,它工作得很好,但是我们希望在同一页面上弹出带有错误消息的消息,这有可能吗?

ErrorBoundary组件代码如下所示:

import React from 'react';
import PhyndMenu from './menu/phyndMenu';
import { Dialog, DialogActionsBar } from '@progress/kendo-react-dialogs';


class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      errorInfo: null
    };
    this.toggleDialog = this.toggleDialog.bind(this);
  }
  toggleDialog() {
    this.setState({
        visible: !this.state.visible
    });
}
  componentDidCatch(error, errorInfo) {
    // Catch errors in any child components and re-renders with an error message
    this.setState({
      error: error,
      errorInfo: errorInfo
    });
  }

  render() {

    let routeHtml = '';
    routeHtml = 
      <div>
        <footer className="footer">
        <div className="text-center">
            <div className="inlineBlock">© Copyright 2018 PHYND TECHNOLOGIES, INC. All rights reserved. Version 3.4</div>
            <nav className="inlineBlock">
                <a href="http://www.phynd.com/Privacy" target="_blank">Privacy Policy</a>|  
                <a href="http://www.phynd.com/Terms" target="_blank">Terms and Conditions </a>
                |  <a href="mailto:support@phynd.com">Support</a>
            </nav>
            </div>
    </footer>
    </div>


    if (this.state.error) {
      // Fallback UI if an error occurs
      return (
        <div>
          <header className="NetworkMgmt-header">
            <PhyndMenu />
          </header>
          {/* <div style={{minHeight:"1000px"}} >
            <h2>{"Oh-no! Something went wrong"}</h2>
          </div>
          {routeHtml} */}
          {this.props.children}
          <div>
                <button className="k-button" onClick={this.toggleDialog}>Open Dialog</button>
                {this.state.visible && <Dialog title={"Please confirm"} onClose={this.toggleDialog}>
                    <p style={{ margin: "25px", textAlign: "center" }}>Are you sure you want to continue?</p>
                    <DialogActionsBar>
                        <button className="k-button" onClick={this.toggleDialog}>No</button>
                        <button className="k-button" onClick={this.toggleDialog}>Yes</button>
                    </DialogActionsBar>
                </Dialog>}
            </div>
          </div>
      );
    }
    // component normally just renders children
    return this.props.children;
  }
}

export default ErrorBoundary;

这就是我们如何注册我们的ErrorBoundary组件:

 <Provider store={store}>

        <Router>
        <ErrorBoundary>
            <CookiesProvider>
                <NetworkMgmt />
            </CookiesProvider>
            </ErrorBoundary>
        </Router>
    </Provider>,

在@Trent的建议下,我已经实现了我的ErrorBoundary之类的东西,但是显示空白页:

import React from 'react';
import PhyndMenu from './menu/phyndMenu';
import ReactDOM from 'react-dom';
const modalRoot = document.getElementById('modal-root');
// Let's create a Modal component that is an abstraction around
// the portal API.
class Modal extends React.Component {
  constructor(props) {
    super(props);
    // Create a div that we'll render the modal into. Because each
    // Modal component has its own element, we can render multiple
    // modal components into the modal container.
    this.el = document.createElement('div');
  }

  componentDidMount() {
    // Append the element into the DOM on mount. We'll render
    // into the modal container element (see the HTML tab).
    modalRoot.appendChild(this.el);
  }

  componentWillUnmount() {
    // Remove the element from the DOM when we unmount
    modalRoot.removeChild(this.el);
  }

  render() {
    // Use a portal to render the children into the element
    return ReactDOM.createPortal(
      // Any valid React child: JSX, strings, arrays, etc.
      this.props.children,
      // A DOM element
      this.el,
    );
  }
}
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      errorInfo: null
    };
  }

  componentDidCatch(error, errorInfo) {
    // Catch errors in any child components and re-renders with an error message
    this.setState({
      error: error,
      errorInfo: errorInfo
    });
  }

  render() {

    const modal =
      <Modal>
        <div className="modal">
          <div>
            With a portal, we can render content into a different
            part of the DOM, as if it were any other React child.
          </div>
        </div>
      </Modal>

    return (
      <div className="app">
       {modal}
      </div>
    );
  }
}

export default ErrorBoundary;

1 个答案:

答案 0 :(得分:0)

当然!看起来您的错误消息“冒泡了”到您的ErrorBoundary组件。

在ErrorBoundary的render方法内,您可以使用React Portal在DOM树中向上渲染div,将其设置为模式,并将其绝对定位在Web应用程序上。 / p>

在React Portal文档中有一个创建模态的示例: https://reactjs.org/docs/portals.html#event-bubbling-through-portals