最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - React Javascript Handle Possible Null Data - Stack Overflow

programmeradmin0浏览0评论

I am using React to build a simple app that gets data back from some API. I am not sure what is the best way to handle the fields when some of them doesnt e back. For example, Let's say the JSON data es back looking like the following

icDetail : {
    name : iron man, 
    age: {
        icAge: 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 
        }            
    }
}

My React code that renders the data

renderComicDetail() {
    var cd = this.propsicDetail;        
    if (!cd) {
        return (
            <div>No Data</div>
        )
    }
    const imageUrl = cd.collection.image
    return (
        <div>
            <div>age: {cd.ageicAge}</div>                
            <div>favourite fruit: {cd.favouriteFood.fruit}</div>                
            <div>favourite hobby: {cd.hobby.favourite}</div>                
        </div>
    )
}

This code will break if either of the of cd.favouriteFood, cd.age, cd.hobby is undefined as I will be reading from undefined. (This will happen as not all fields will e back) What is the cleanest way to allow me to read the data and take care of the undefined case so I dont read .fruit from undefined.

A way I can think of is to have check cases for each part of the json data for every item. But it seems messy and will not be scalable as I might have data that looks like

I am using React to build a simple app that gets data back from some API. I am not sure what is the best way to handle the fields when some of them doesnt e back. For example, Let's say the JSON data es back looking like the following

icDetail : {
    name : iron man, 
    age: {
        icAge: 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. 
        }            
    }
}

My React code that renders the data

renderComicDetail() {
    var cd = this.props.icDetail;        
    if (!cd) {
        return (
            <div>No Data</div>
        )
    }
    const imageUrl = cd.collection.image
    return (
        <div>
            <div>age: {cd.age.icAge}</div>                
            <div>favourite fruit: {cd.favouriteFood.fruit}</div>                
            <div>favourite hobby: {cd.hobby.favourite}</div>                
        </div>
    )
}

This code will break if either of the of cd.favouriteFood, cd.age, cd.hobby is undefined as I will be reading from undefined. (This will happen as not all fields will e back) What is the cleanest way to allow me to read the data and take care of the undefined case so I dont read .fruit from undefined.

A way I can think of is to have check cases for each part of the json data for every item. But it seems messy and will not be scalable as I might have data that looks like

Share Improve this question asked Apr 29, 2017 at 4:17 ErnieKevErnieKev 3,0415 gold badges23 silver badges35 bronze badges 1
  • You can do conditional rendering and then do a check to see if the specific part is undefined before accessing it. – Andrew Li Commented Apr 29, 2017 at 4:20
Add a ment  | 

7 Answers 7

Reset to default 2

You can specify a condition to render a ponent in JSX, your code would look something like this (assuming that if hobby or food are defined then it would have renderable properties):

var cd = this.props.icDetail;        
    if (!cd) {
        return (
            <div>No Data</div>
        )
    }
    const imageUrl = cd.collection.image;


    return (
        <div>
            <div>age: {cd.age.icAge}</div>                
            {cd.favouriteFood && <div>favourite fruit: {cd.favouriteFood.fruit}</div>}
            {cd.hobby && <div>favourite hobby: {cd.hobby.favourite}</div>}
        </div>
    )

I also advice you to either create separate ponet for both hobby and food, so it can make your code more readable and reusable. But it definitely depends on your specific usage.

if you only don't want to display content which is undefined, you can do like this:

return (
        <div>
            {cd.age && cd.age.icAge ? <div>age:{cd.age.icAge}</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>
    )

or if you don't want like this, create a separate function that checks valid fields

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

You can use any JSON schema validator for this purpose and there are lots of them. for e.g jsonschema

In your case you can create schema something like this ( for first two properties)

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

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

You can also embed two or more schema together and form a new schema.

One way to access deep object property using lodash. You can import lodash in your ponent.

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

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

To make the code cleaner, You can also declare a function that takes your object(i.e. cd in your case) and path(i.e. favouriteFood.fruit in your case) and return the value from function.

I really like this method of un-nesting objects:

// Below will not error out, but give undefined when you use the non-existant variables
const { cd } = (this.props || {}).icDetail || {}
const { imageUrl } = ((cd || {}).collection || {}).image || {}

// Or
const { age, favouriteFood, hobby } = cd
const { icAge } = age // forgot if you need to add || {} here
const { fruit } = favouriteFood
const { favourite } = hobby

You always want to validate your variables and you never want your variables to break during validation.

So now, you can safely use these 'potentially' undefined variables and validate that they contain values before you use them.

favorite || 'defaultValue'
if (!favorite) return null 

How about use ternary operator?

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

You can try your return statement such like that:

return (
        <div>
            { cd.age.icAge && <div>age: {cd.age.icAge }</div>}
            { cd.favouriteFood.fruit &&  <div>favourite fruit: {cd.favouriteFood.fruit}</div> }          

            {cd.hobby.favourite &&  <div>favourite hobby: {cd.hobby.favourite}</div>                
        </div>
    )

If your any prop is null or undefined, the right side of the condition is skipped.

发布评论

评论列表(0)

  1. 暂无评论