反应Javascript处理可能的空数据

时间:2017-04-29 04:17:48

标签: javascript reactjs react-redux

我正在使用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中读取。 (这将发生,因为并非所有字段都会返回) 什么是允许我阅读数据并处理未定义案例的最简洁方法,所以我不读取未定义的.fruit。

我能想到的一种方法是为每个项目提供json数据的每个部分的检查案例。但它似乎很混乱,并且不可扩展,因为我可能有类似

的数据

7 个答案:

答案 0 :(得分:2)

您可以指定在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>
    )

我还建议您为爱好和食物创建单独的组件,这样可以使您的代码更具可读性和可重用性。但这绝对取决于您的具体用法。

答案 1 :(得分:1)

如果您只是不想显示未定义的内容,可以这样做:

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

答案 2 :(得分:0)

如何使用terinary运算符?

cd.age!== undefined? cd.age.comicAge:&#39; &#39;

答案 3 :(得分:0)

您可以为此目的使用任何JSON模式验证器,并且有很多它们。例如jsonschema

在您的情况下,您可以创建类似这样的模式(对于前两个属性)

var schema = {
"id": "/ComicDetail",
"type": "object",
"properties": {
    "name": {
        "type": "string"
    },

    "age": {
        "type": "object",
        "properties": {
            "comicAge": {
                "type": "integer"
            }
        }
    }
},
"required": ["name", "age"]
};

您还可以将两个或多个架构嵌入在一起并形成新架构。

答案 4 :(得分:0)

使用lodash访问深层对象属性的一种方法。您可以在组件中导入lodash。

_.get(cd, 'favouriteFood.fruit') || ''

https://lodash.com/docs/4.16.6#get

为了使代码更清晰,您还可以声明一个函数,它接受您的对象(即您的情况下为cd)和路径(即您的情况下为favouriteFood.fruit)并返回函数中的值。

答案 5 :(得分:0)

我真的很喜欢这种取消嵌套对象的方法:

// 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 

答案 6 :(得分:-1)

您可以尝试这样的退货声明:

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>
    )

如果您的任何道具为空或未定义,则跳过条件的右侧。