javascript - 构建高阶组件误差边界
问题描述
我正在处理的项目需要更好的错误处理,并且开始我决定实施反应 ErrorBoundary 钩子 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"));
错误边界应该是一个包装器组件,因此您可以将有用的道具传递给它,在多种用途上更容易重用案例,等等:
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>
</>
- 请参阅类似的问题:ErrorBoundary 实际上做了什么。
推荐阅读
- java - 了解正则表达式以从字符串中删除 HTML 标记
- python - 我应该如何使以下打印语句为一行的每个部分占用一致的空格数?
- php - 定义一个类来调用它的函数,但它无法识别并显示错误
- grpc - 使用 gevent 和 grpc 缩放问题
- javascript - 如何使用 JavaScript RegExp 捕获特定组?
- javascript - Redux createStore 源代码 - 增强器递归回调部分的无限循环风险?
- javascript - (Vanilla JS)使用单击事件侦听器捕获数组元素的索引?
- arrays - 确定Ruby中嵌套数组的中值元素?
- java - 使用 mapreduce 的第二大薪水 - 输出不如预期
- javascript - JQuery ajax 不适用于特定的输入字符串参数“
我正在使用字符串输入参数进行 JQuery ajax 调用,如下所示。但是每当输入参数值为“
<?
”时,ajax调用甚至没有命中服务层中的控制器方法就失败了。但这适用于所有输入值,如“<”、“?”、“<*”等。这仅适用于该输入“
<?
”。在控制器服务方法中,如果我将输入参数值硬编