There is a notifications component within a popover that makes a fetch call.
The connection fails and cannot reach the resources.
The error boundary component wraps the notifications component.
It is expected that after the connection fails, will show a custom component that says there is a problem along with a button to retry the connection.
However, the behavior of the error boundary is: It pauses while the popover is open (nothing is shown) and then just a few moments before it closes, it displays the custom component to retry the connection and the popover finishes closing.
export default function PopOver() {
const [anchorNotificationEl, setAnchorNotificationEl] = React.useState(null);
const popoverNotiRef = React.useRef(null);
const isNotificationOpen = Boolean(anchorNotificationEl);
const handleClick = (event) => {
setAnchorNotificationEl(event.currentTarget);
};
const handleNotificationClose = () => {
setAnchorNotificationEl(null);
};
const notificationId = 'notification-popover';
return (
<>
<IconButtonCustom
aria-label="show 17 new notifications"
color="inherit"
onClick={handleClick}
id="notifications-icon"
>
<Badge
badgeContent={0}
color="secondary"
>
<NotificationsIcon
fontSize="large"
/>
</Badge>
</IconButtonCustom>
<Popover
ref={popoverNotiRef}
id={notificationId}
open={isNotificationOpen}
anchorEl={anchorNotificationEl}
onClose={handleNotificationClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
elevation={1}
>
<Notifications popoverRef={popoverNotiRef.current} />
</Popover>
</>
);
}
class ErrorBoundary extends React.Component <Props, State> {
constructor(props) {
super(props);
this.state = { error: null };
}
static getDerivedStateFromError(error): State {
return { error };
}
componentDidCatch(error) {
this.setState({ error });
}
render() {
const { children, fallback } = this.props;
const { error } = this.state;
if (error) {
if (fallback) {
return fallback;
}
return <p>Something is wrong</p>;
}
return children;
}
}
export default function NotificationWrapper({ popoverRef }: NWProps) {
const [queryReference, loadQuery] = useQueryLoader(NotificationsQuery);
useEffect(() => {
loadQuery({
count: 5,
}, { fetchPolicy: 'store-and-network' });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<>
<ErrorBoundary fallback={<RetryComponent loadQuery={loadQuery}/>}>
{queryReference && (
<Suspense fallback={<Loading />}>
<NotificationsIntermediate queryRef={queryReference} popoverRef={popoverRef} />
</Suspense>
)}
</ErrorBoundary>
</>
);
}