Reputation: 53
I am calling a general component called cmsBlock in Magento PWA. I can't really do many changes to that component as it is used in many pages. However on my CartPage I want to render null if the CMS-block throws error ( i e the CMS block is disabled and the identifier cannot be found).
The problem is that in cmsBlock.js an error actually renders something ( I can add a className, but that is basically all I am allowed do to that component, so no ErrorBoundary can be used on csmBlock) so I cannot check for null or undefined:
const { loading, error, data } = useQuery(GET_CMS_BLOCKS, {
variables: { identifiers }
});
if (loading) {
return fullPageLoadingIndicator;
}
if (error) {
return <div>Data Fetch Error</div>;
}
So that means I always get true when calling CMS-blocks. In my Cart page I have tried this (cartPage.js):
const cmsBlock = <CmsBlock identifiers={'cartpage-block'} />;
const cmsBlockHolder =
cmsBlock ? (
<div className={classes.cmsblock}>
</div>
) : null;
But I need to add an additional condition to check if the cmsBlock component return error, because then I should not allow to render the cmsBlockHolder at all. Any ideas on how to solve this without changing the cmsBlock.js?
Upvotes: 0
Views: 160
Reputation: 8982
This sounds like you look for Error Boundaries. Quoting the react docs:
Error boundaries work like a JavaScript catch {} block, but for components
What you have to do is define a new component which includes the lifecycle method getDerivedStateFromError(). There you can render a fallback UI if a child component throws an error. It could look like this for your use case:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return null;
}
return this.props.children;
}
}
And your component composition would look like this:
<ErrorBoundary>
<CmsBlock />
</ErrorBoundary>
Upvotes: 0