【问题标题】:How can I make my React child components render even if a prop is missing即使缺少道具,如何使我的 React 子组件呈现
【发布时间】:2017-09-22 04:59:19
【问题描述】:

TLDR;即使 this.props 的属性丢失,我也需要能够在 React 中渲染子组件。

我有一个使用 Yahoo's Flxubile 构建的 React 应用程序。该应用程序使用 WP REST API 从 Wordpress 站点获取数据。有时可能会丢失图像或 API 中的其他内容,这会导致客户端中断。这是一个例子:

我有一个名为 Articles.js 的文件,它连接到保存我的文章的 ArticlesStore。然后,我为我拥有的每篇文章渲染一个 Article.js,并像这样传递道具:

{   this.props.articles.map(function(el, index) {                                           
      return <Article key={index} article={el} />
    })
}

这里一切正常,但是在我的 Article.js 中,当我尝试访问未设置的属性时,我得到以下信息:

未捕获的类型错误:无法读取未定义的属性“大小”

这是导致错误的行:

<img src={this.props.article.meta_fields.image.sizes.large} />

当文章中缺少图片时会发生这种情况。我当然理解 javascript 错误,但如果 API/Store 中缺少图像 url,我想呈现 Article.js 组件事件。我尝试了以下解决方案,但它会导致过于混乱且无法控制:

  1. 如果我们有道具即条件集 {this.props.article.meta_fields.image ? this.props.article.meta_fields.image.sizes.large : "imagemissing.png"}
  2. 设置默认道具。这不起作用,因为从父级传递到子级的属性会覆盖 defaultProps。

除了将道具从父母传给孩子之外,也许我应该尝试其他方法?有一个 ArticleStore,我可以在其中为每篇文章设置默认值吗?你会怎么做?

【问题讨论】:

  • 你不能在 render 中设置一个关于 prop 是否存在的条件,如果不存在则不带图像返回它吗?
  • 我也遇到了同样的问题,用默认值解决了,为什么不给控制?
  • @cbll 然后我必须为我拥有的每个组件制作大约 10 个条件。会很混乱,我不得不花很多时间来写条件。
  • @donquixote 存储或组件中的默认值?因为我不能使用 defaultProps,因为它在孩子中被覆盖了。
  • 在组件@SebastianMarcusson

标签: javascript reactjs store fluxible


【解决方案1】:

如果您想提供一个嵌套结构作为道具(如article),您将希望能够依赖始终几乎相同的结构。在这种情况下它不会,有时meta_fields 没有image-attribute(正如您的 TypeError 所暗示的那样)。

在你的情况下,我会考虑从文章对象中提取你在Article 组件中实际需要/使用的东西,并将它们作为道具传递。

假设您的Article 仅使用titlebodyimage。然后将它们作为道具传递。

<Article title={ article.title } body={ article.body } image={ getImage(article) }/>

function getImage(article) {
    if (article.meta_fields.image
     && article.meta_fields.image.sizes
     && article.meta_fields.image.sizes.large
    ) {
        return article.meta_fields.image.sizes.large;
    }
    return 'default_image.jpg'; // Or whatever you want.
}

可能有人会认为额外的道具在这里构成了更多的“混乱”,但考虑到混乱和TypeError之间的选择,我选择了混乱。

如果您不想重新发明轮子。像这种嵌套结构访问数据的问题之前已经解决了。

// Lodash
_.get(article, 'meta_fields.image.sizes.large', 'default_image.jpg')
// Ramda
_.pathOr('default_image.jpg', ['meta_fields', 'image', 'sizes', 'large'], article)

【讨论】:

  • 我选择了 Lodash 解决方案。它最适合我的需求。
猜你喜欢
  • 2021-04-30
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-25
  • 1970-01-01
  • 2020-12-26
  • 2021-05-05
相关资源
最近更新 更多