我正在使用React构建一个从某些API获取数据的简单应用程序。当他们中的一些人没有回来时,我不确定处理这些领域的最佳方法是什么。例如,假设JSON数据返回如下所示
comicDetail : {
name : iron man,
age: {
comicAge: 35,
},
favouriteFood: {
fruit: {
apple
}
}
hobby: {
favourite: {
build machines
}
}
series: [iron man 1, iron man 2]
relationship: {
jane: iron man 1,
Mary: iron man 2
},
collection : {
image : www.image1.com
}
}
}
我的React代码,用于呈现数据
renderComicDetail() {
var cd = this.props.comicDetail;
if (!cd) {
return (
<div>No Data</div>
)
}
const imageUrl = cd.collection.image
return (
<div>
<div>age: {cd.age.comicAge}</div>
<div>favourite fruit: {cd.favouriteFood.fruit}</div>
<div>favourite hobby: {cd.hobby.favourite}</div>
</div>
)
}
如果cd.favouriteFood,cd.age,cd.hobby中的任何一个未定义,则此代码将中断,因为我将从undefined中读取。 (这将发生,因为并非所有字段都会返回)允许我读取数据并处理未定义的情况的最简洁方法是什么,所以我不读取undefined中的.fruit。
我能想到的一种方法是为每个项目提供json数据的每个部分的检查案例。但它似乎很混乱,并且不可扩展,因为我可能有类似的数据
您可以指定在JSX中呈现组件的条件,您的代码看起来像这样(假设如果定义了爱好或食物,那么它将具有可渲染属性):
var cd = this.props.comicDetail;
if (!cd) {
return (
<div>No Data</div>
)
}
const imageUrl = cd.collection.image;
return (
<div>
<div>age: {cd.age.comicAge}</div>
{cd.favouriteFood && <div>favourite fruit: {cd.favouriteFood.fruit}</div>}
{cd.hobby && <div>favourite hobby: {cd.hobby.favourite}</div>}
</div>
)
我还建议您为业余爱好和食物创建单独的组件,这样可以使您的代码更具可读性和可重用性。但这绝对取决于您的具体用法。
如果您只是不想显示未定义的内容,可以这样做:
return (
<div>
{cd.age && cd.age.comicAge ? <div>age:{cd.age.comicAge}</div> : <div>No data</div>
}
{cd.favouriteFood && cd.favouriteFood.fruit ? <div>favourite fruit: {cd.favouriteFood.fruit}</div> : <div>No data</div>
}
{cd.hobby && cd.hobby.favourite ? <div>favourite hobby: {cd.hobby.favourite}</div> : <div>No data</div>
}
</div>
)
或者如果您不想这样,请创建一个单独的函数来检查有效字段
if (!isValid(cd)) {
return (
<div>No Data</div>
)
}
isValid(obj){
// check if all objects available are valid or not and return true or false as needed.
}
如何使用三元运算符?
cd.age!== undefined? cd.age.comicAge:''
您可以为此目的使用任何JSON模式验证器,并且有很多它们。例如jsonschema
在您的情况下,您可以创建类似这样的模式(对于前两个属性)
var schema = {
"id": "/ComicDetail",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "object",
"properties": {
"comicAge": {
"type": "integer"
}
}
}
},
"required": ["name", "age"]
};
您还可以将两个或更多模式嵌入在一起并形成新模式。
使用lodash访问深层对象属性的一种方法。您可以在组件中导入lodash。
_.get(cd, 'favouriteFood.fruit') || ''
https://lodash.com/docs/4.16.6#get
为了使代码更清晰,您还可以声明一个函数,它接受您的对象(即您的情况下的cd)和路径(即您的情况下的favouriteFood.fruit)并返回函数中的值。
我真的很喜欢这种取消嵌套对象的方法:
// Below will not error out, but give undefined when you use the non-existant variables
const { cd } = (this.props || {}).comicDetail || {}
const { imageUrl } = ((cd || {}).collection || {}).image || {}
// Or
const { age, favouriteFood, hobby } = cd
const { comicAge } = age // forgot if you need to add || {} here
const { fruit } = favouriteFood
const { favourite } = hobby
您始终希望验证变量,并且在验证期间永远不希望变量中断。
所以现在,您可以安全地使用这些“潜在的”未定义变量,并在使用它们之前验证它们是否包含值。
favorite || 'defaultValue'
if (!favorite) return null
您可以尝试这样的return语句:
return (
<div>
{ cd.age.comicAge && <div>age: {cd.age.comicAge }</div>}
{ cd.favouriteFood.fruit && <div>favourite fruit: {cd.favouriteFood.fruit}</div> }
{cd.hobby.favourite && <div>favourite hobby: {cd.hobby.favourite}</div>
</div>
)
如果您的任何道具为null或未定义,则跳过条件的右侧。