反应Javascript处理可能的空数据

问题描述 投票:5回答:7

我正在使用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数据的每个部分的检查案例。但它似乎很混乱,并且不可扩展,因为我可能有类似的数据

javascript reactjs react-redux
7个回答
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
投票

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

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

0
投票

如何使用三元运算符?

cd.age!== undefined? cd.age.comicAge:''


0
投票

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

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

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

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

您还可以将两个或更多模式嵌入在一起并形成新模式。


0
投票

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

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

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

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


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 

-1
投票

您可以尝试这样的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或未定义,则跳过条件的右侧。

© www.soinside.com 2019 - 2024. All rights reserved.