import React, { lazy, Suspense } from "react";
/**
* A higher-order component that wraps child components in an error boundary
* and provides a fallback loading UI using React Suspense.
* @interface
* @param {object} props - The component's props.
* @returns {JSX.Element} The SuspenseWrapper component.
*/
const SuspenseWrapper = (props) => {
return (
<ErrorBoundary>
<Suspense fallback={<Loading />}>{props.children}</Suspense>;
</ErrorBoundary>
);
};
export default SuspenseWrapper;
/**
* Custom style for the loading component.
*/
const customStyle = {
height: "100vh",
width: "100vw",
display: "flex",
alignItems: "center",
justifyContent: "center",
};
/**
* A loading component displayed while the main content is loading.
* @returns {JSX.Element} The Loading component.
*/
const Loading = () => <div style={customStyle}>Loading</div>;
/**
* An error boundary component that catches errors in its children components.
* @class
*/
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { error: null, errorInfo: null };
}
/**
* Catches errors that occur in the child components.
* @param {Error} error - The error that was caught.
* @param {object} errorInfo - Additional information about the error.
*/
componentDidCatch(error, errorInfo) {
this.setState({
error: error,
errorInfo: errorInfo,
});
}
render() {
if (this.state.errorInfo) {
// Error path
return (
<div>
<h2>Something went wrong.</h2>
<details style={{ whiteSpace: "pre-wrap" }}>
{this.state.error && this.state.error.toString()}
<br />
{this.state.errorInfo.componentStack}
</details>
</div>
);
}
// Normally, just render children
return this.props.children;
}
}
Source