【问题标题】:Check if React component throws error from another component检查 React 组件是否从另一个组件抛出错误
【发布时间】:2021-01-26 13:36:01
【问题描述】:

我在 Magento PWA 中调用了一个名为 cmsBlock 的通用组件。我不能对该组件进行太多更改,因为它在许多页面中使用。但是在我的 CartPage 上,如果 CMS 块抛出错误(即 CMS 块被禁用并且找不到标识符),我想呈现 null。

问题在于,在 cmsBlock.js 中,错误实际上会呈现一些东西(我可以添加一个类名,但这基本上是我允许对该组件所做的所有事情,因此不能使用 ErrorBoundary csmBlock),所以我无法检查 null 或 undefined:

 const { loading, error, data } = useQuery(GET_CMS_BLOCKS, {
    variables: { identifiers }
});

if (loading) {
    return fullPageLoadingIndicator;
}

if (error) {
    return <div>Data Fetch Error</div>;
}

这意味着我在调用 CMS 块时总是正确的。 在我的购物车页面中,我尝试过这个(cartPage.js):

const cmsBlock = <CmsBlock identifiers={'cartpage-block'} />;

const cmsBlockHolder =
    cmsBlock ? (
        <div className={classes.cmsblock}>              
        </div>
    ) : null;

但是我需要添加一个额外的条件来检查 cmsBlock 组件是否返回错误,因为这样我就不应该允许渲染 cmsBlockHolder。关于如何在不更改 cmsBlock.js 的情况下解决此问题的任何想法?

【问题讨论】:

    标签: reactjs magento progressive-web-apps venia


    【解决方案1】:

    这听起来像是您在寻找Error Boundaries。引用反应文档:

    错误边界的工作方式类似于 JavaScript catch {} 块,但用于组件

    您要做的是定义一个新组件,其中包含 lifecycle 方法 getDerivedStateFromError()。如果子组件抛出错误,您可以在那里呈现回退 UI。对于您的用例,它可能看起来像这样:

    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;
      }
    }
    

    您的组件组合将如下所示:

    <ErrorBoundary>
      <CmsBlock />
    </ErrorBoundary>
    

    【讨论】:

    • 我已经在 CartPage 中尝试过(但没有成功),我不允许在 cmsBlock-component 中这样做
    • 但这在 CMS 组件之外。所以你不要编辑那个。好的,如果这不起作用,您是否考虑过添加 ref 并检查孩子是否有特定的类,或者可能通过 document.getElementByClassName 执行此操作?
    • 但是在客户端渲染时会起作用吗?如果CMSBlock背景闪烁然后消失,用户将不高兴。
    • 嗯,好问题。不幸的是,我无法真正回答这个问题。对不起。
    • 您的解决方案的问题是必须将其应用于 cmsBlock 才能正常工作。而且我可能不会更改该文件
    猜你喜欢
    • 2018-12-10
    • 2017-02-02
    • 1970-01-01
    • 2020-12-23
    • 2021-12-20
    • 2018-05-18
    • 2023-03-04
    • 2022-08-17
    • 2022-01-04
    相关资源
    最近更新 更多