javascript - 构建高阶组件误差边界

标签 javascript reactjs error-handling components higher-order-components

我正在从事的项目需要更好的错误处理,首先我决定实现 React ErrorBoundary 钩子(Hook) componentDidCatch,我可以在单个组件中简单地实现它。然而,一位高级开发人员建议我将错误边界设为高阶组件,以便我可以将整个应用程序包装在其中。这就是我遇到麻烦的地方,因为尽管阅读了文档,但高阶组件对我来说毫无意义。

这是我到目前为止所实现的:

我的HOC

import React from "react";
import ErrorScreen from "./ErrorScreen"


export default function NewErrorHandler(WrappedComponent) {
 class ErrorHandler extends React.Component {
    constructor(props) {
        this.state = {hasError: false}
    };

    componentDidCatch(error, info) {
        this.setState({ hasError: true })
    }

    render() {
        if(this.state.hasError) {
            return (
                <ErrorScreen/> 
            )
        } else {
            return this.props.children
        }
    }
}
}

到目前为止,我的问题是我不确定如何将应用程序包装在错误边界中。在我看到的所有示例中,HOC 都可以通过导出轻松地封装功能组件,但是该应用程序的设置方式没有我可以看到的显式导出函数:

import ReactDOM from "react-dom";
import React from "react";
import { store, history } from "./store";
import { Provider } from "react-redux";
import { Route, Switch } from "react-router"; // react-router v4
import { ConnectedRouter } from "connected-react-router";
import DetectAdblock from "./components/DetectAdblock";
import ErrorBound from "./components/ErrorHOC";

const Encounter = Loadable({
  loader: () => import("./components/Encounter/Encounter"),
  loading: Loading,
  delay: 300
});

const VerifyInsuranceList = Loadable({
  loader: () => import("./components/VerifyInsurance/InsuranceList"),
  loading: Loading,
  delay: 300
});

const VideoChat = Loadable({
  loader: () => import("./components/VideoChat"),
  loading: Loading,
  delay: 300
});

document.addEventListener("DOMContentLoaded", () => {
  ReactDOM.render(
    
<Provider store={store}>
        <ConnectedRouter history={history}>
          <TokenLoader>
            <DetectAdblock />
            <BrowserBanner />
            <EnvBanner />
            <IdleMonitor />
            <TokenRefresher />
            <MonotonicClock frequency={15} />
            <RtcMonitor />
            <PatientPoller pollInterval={30000} />
            <Redirect />
            <Switch>
              <Route exact={true} path="/" component={ProviderDashboard} />
              <Route
                exact={true}
                path="/accept-invitation/:inviteID"
                component={AcceptInvite}
              />
              <Route exact={true} path="/login" component={Login} />
              <Route
                exact={true}
                path="/reset-password/:resetID"
                component={ResetPassword}
              />
              <Route
                exact={true}
                path="/request-password-reset"
                component={ForgotPassword}
              />
              <Route
                exact={true}
                path="/waiting-room"
                component={ProviderAvailablePatients}
              />
              <Route exact={true} path="/encounter" component={Encounter} />
              <Route exact={true} path="/video" component={VideoChat} />
              <Route
                exact={true}
                path="/providers"
                component={ManagerProviders}
              />
              <Route exact={true} path="/providers/new" component={Invite} />
              <Route
                exact={true}
                path="/providers/edit/:providerID"
                component={ProviderEdit}
              />
              <Route
                exact={true}
                path="/providers/audit/:providerID"
                component={ProviderAudit}
              />
              <Route
                exact={true}
                path="/activity-monitor"
                component={ActivitySummary}
              />
              <Route
                exact={true}
                path="/encounter-monitor"
                component={EncounterMonitor}
              />
              <Route
                exact={true}
                path="/encounter-monitor/:encounterID"
                component={EncounterMonitorDetails}
              />
              <Route exact={true} path="/billing" component={BillingTab} />
              <Route exact={true} path="/patients" component={PatientTab} />
              <Route exact={true} path="/rounding" component={RoundingTab} />
              <Route
                exact={true}
                path="/patients/:patientID"
                component={PatientChart}
              />
              <Route
                exact={true}
                path="/active-patient-chart/:patientID"
                component={ActivePatientChart}
              />
              <Route
                exact={true}
                path="/insurnace-history/:patientID"
                component={InsuranceHistory}
              />
              <Route
                exact={true}
                path="/verify-insurance"
                component={VerifyInsuranceList}
              />
              <Route render={() => <div>Not Found</div>} />
            </Switch>
          </TokenLoader>
        </ConnectedRouter>
      </Provider>
document.getElementById("app")
  );
});

这里我省略了一些导入语句,但展示了如何导入 ErrorHOC.js。任何关于如何包装整个应用程序的见解都会非常有帮助。如果我缺少理解所需的信息,请告诉我。

最佳答案

正如评论中所讨论的,错误边界不是 HOC 的用例,这里无论如何都是逻辑应该如何工作的可能示例:

// withErrorBoundary.js
class ErrorHandler extends React.Component {}

// HOC wrapping the passed component
export default function withErrorBoundary(WrappedComponent) {
  const Component = (
    <ErrorHandler>
      <WrappedComponent />
    </ErrorHandler>
  );
  return Component;
}

// index.js
import withErrorBoundary from "./withErrorBoundary.js";

const App = <Provider store={store}>...</Provider>;

// Usage
const AppWithErrorBoundary = withErrorBoundary(App);

ReactDOM.render(<AppWithErrorBoundary />, document.getElementById("app"));

错误边界应该是一个包装组件,这样你就可以向它传递有用的 Prop ,更容易在多种用途上重用,等等:

class ErrorBoundaryWrapper extends React.Component {
  render() {
    return (
      <>
        {/** Use other props passed to wrapper **/}
        <div>...</div>
        {this.props.children}
      </>
    );
  }
}

// Usage, see the advantage over HOC
<>
  <ErrorBoundaryWrapper specialProps={props1}>
    <Component1 />
  </ErrorBoundaryWrapper>
  <ErrorBoundaryWrapper specialProps={props2}>
    <Component2 />
  </ErrorBoundaryWrapper>
</>

关于javascript - 构建高阶组件误差边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65567374/

相关文章:

php - Ajax + 后退和前进按钮

javascript - 未找到 Webpack block

javascript - 非标记返回时没有键的映射

error-handling - 将 .NET Framework 4.5 的 System.IO.FileSystemWatcher 的设置配置为可就错误、容错、健壮、智能等进行交流

python - “try…except”的效率

javascript - 如何修复 webpack 的快速警告?

javascript - 在angularjs中将字符串转换为对象时出错

javascript - IE 递归中的堆栈溢出 -> window.frames 不等于自身

javascript - react 更新状态奇怪的行为

c# - 如何在 C# 中使用 using 语句进行错误处理