嵌套错误边界

Ker*_*ina 5 reactjs

我正在考虑在ReactJS中针对特定用例执行嵌套错误边界:

  • 在子组件中显示错误视图
  • 在父组件中显示错误对话框
    <ErrorBoundary1>
        <ErrorBoundary2><child1 /></ErrorBoundary2>
        <ErrorBoundary2><child2 /></ErrorBoundary2>
    </ErrorBoundary1>
Run Code Online (Sandbox Code Playgroud)

我已经尝试过这样做,但是当发生错误时,似乎没有通过父错误边界。我可以componentDidCatch对内部错误边界进行抛出,但这将使其陷入无限循环。

有什么建议吗?

Ric*_*her 6

嵌套错误边界是一回事,但只有当子边界失败时,父边界才会发挥作用(或者render,正如您发现的那样,错误componentDidCatch)。尽管我无法复制您对内部边界循环的体验:它在投掷时立即死亡。

class DialogErrorBoundary extends React.Component {
  state = {
    hasError: false
  };

  static getDerivedStateFromError() {
    return {
      hasError: true
    };
  }

  render() {
    return this.state.hasError ? <div>DIALOG ERROR</div> : this.props.children;
  }
}

class ErrorBoundary extends React.Component {
  state = {
    hasError: false
  };

  componentDidCatch(error) {
    throw error;
  }

  static getDerivedStateFromError(error) {
    return {
      hasError: true
    };
  }

  render() {
    return this.state.hasError ? <div>ERROR</div> : this.props.children;
  }
}

class SomeComponent extends React.Component {
  componentDidMount() {
    throw Error("Nope.");
  }

  render() {
    return <div>SOME COMPONENT</div>;
  }
}

function App() {
  return (
    <DialogErrorBoundary>
      <ErrorBoundary>
        <SomeComponent />
      </ErrorBoundary>{" "}
    </DialogErrorBoundary>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)

为了实现您的建议,这给我们留下了组件之间通常的通信方式:

  • 从父组件传递的函数
  • 共享状态、Redux

粗略的目标是:如果存在父边界,则通知它子边界已捕获错误。

然而,此时我们没有利用错误边界机制,只是通知组件显示对话框。因此,虽然有人认为在应用程序的根部设置“包罗万象”的错误边界,但只有在其子边界失败之前,它才能真正发挥作用。