即使缺少道具,我如何使我的 React child 组件呈现
How can I make my React child components render even if a prop is missing
TLDR;即使缺少 this.props 的 属性,我也需要能够在 React 中呈现 child 组件。
我有一个使用 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 中,当我尝试访问未设置的属性时,我得到以下信息:
Uncaught TypeError: Cannot read property 'sizes' of undefined
这是导致错误的行:
<img src={this.props.article.meta_fields.image.sizes.large} />
当文章中缺少图片时会发生这种情况。我当然理解 javascript 错误,但如果 API/Store 中缺少图像 url,我想呈现 Article.js 组件事件。我已经尝试了以下解决方案,但它导致太多混乱和无法控制:
- 条件集如果我们有道具即
{this.props.article.meta_fields.image ? this.props.article.meta_fields.image.sizes.large : "imagemissing.png"}
- 正在设置默认道具。这不起作用,因为从 parent 传递的属性到 child 会覆盖 defaultProps。
也许我应该尝试其他方法,而不是将道具从 parent 传递到 child?有一个可以为每篇文章设置默认值的 ArticleStore 吗?你会怎么做?
如果您想提供嵌套结构作为道具(与 article
一样),您将希望能够依赖该结构始终几乎相同。在这种情况下,它不会,有时 meta_fields
没有 image
属性(正如您的 TypeError 所建议的)。
在你的情况下,我会考虑从文章对象中提取你在 Article
组件中实际 need/use 的东西,并将它们作为道具传递。
假设您的 Article
仅使用 title
、body
和 image
。然后将它们作为道具传递。
<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.
}
这里可能有人认为额外的道具构成了更多的"clutter",但是考虑到杂乱和TypeError
之间的选择,我选择杂乱
如果你不想重新发明轮子。像这样在嵌套结构中访问数据的问题之前已经解决了。
// Lodash
_.get(article, 'meta_fields.image.sizes.large', 'default_image.jpg')
// Ramda
_.pathOr('default_image.jpg', ['meta_fields', 'image', 'sizes', 'large'], article)
TLDR;即使缺少 this.props 的 属性,我也需要能够在 React 中呈现 child 组件。
我有一个使用 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 中,当我尝试访问未设置的属性时,我得到以下信息:
Uncaught TypeError: Cannot read property 'sizes' of undefined
这是导致错误的行:
<img src={this.props.article.meta_fields.image.sizes.large} />
当文章中缺少图片时会发生这种情况。我当然理解 javascript 错误,但如果 API/Store 中缺少图像 url,我想呈现 Article.js 组件事件。我已经尝试了以下解决方案,但它导致太多混乱和无法控制:
- 条件集如果我们有道具即 {this.props.article.meta_fields.image ? this.props.article.meta_fields.image.sizes.large : "imagemissing.png"}
- 正在设置默认道具。这不起作用,因为从 parent 传递的属性到 child 会覆盖 defaultProps。
也许我应该尝试其他方法,而不是将道具从 parent 传递到 child?有一个可以为每篇文章设置默认值的 ArticleStore 吗?你会怎么做?
如果您想提供嵌套结构作为道具(与 article
一样),您将希望能够依赖该结构始终几乎相同。在这种情况下,它不会,有时 meta_fields
没有 image
属性(正如您的 TypeError 所建议的)。
在你的情况下,我会考虑从文章对象中提取你在 Article
组件中实际 need/use 的东西,并将它们作为道具传递。
假设您的 Article
仅使用 title
、body
和 image
。然后将它们作为道具传递。
<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.
}
这里可能有人认为额外的道具构成了更多的"clutter",但是考虑到杂乱和TypeError
之间的选择,我选择杂乱
如果你不想重新发明轮子。像这样在嵌套结构中访问数据的问题之前已经解决了。
// Lodash
_.get(article, 'meta_fields.image.sizes.large', 'default_image.jpg')
// Ramda
_.pathOr('default_image.jpg', ['meta_fields', 'image', 'sizes', 'large'], article)