简体   繁体   中英

Check if React component throws error from another component

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 ( ie 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?

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM