1

What's an efficient/elegant way to access nested data from branches of the state that are only available part of the time?

I'm new to React and this problem keeps coming up. I have an ok grasp on Redux and using middleware like Thunk & Saga for the API stuff, but I still don't understand the proper way to write components so that they're not trying to grab non-existent state.

For example, when loading a user's profile photo into a header after the user signs in, the URL will be in the redux store as state.user.userData.photos.primary ...if I try to access that location when the user hasn't signed in, userData is still undefined and React will throw an error. So my solution has been to write assignments like:

let profilePhoto = props.user.userData ? props.user.userData.photos.primary : '';

... which seems cumbersome and inefficient, especially since it requires mapping the entire userData object in mapStateToProps only for the sake of accessing a tiny chunk of data.

I wish I could target it earlier. For example, in mapStateToProps:

profilePhoto : state.user.userData.photos.primary || '';

...but that results in "can't access 'photos' of undefined". So what's an efficient/elegant way to access nested data from branches of the state that are only available part of the time?

1
  • it doesn't qualify as an answer, but anyways: a.) try have a satisfactory default state when initializing the store - or have some helpers like getPrimaryPhoto(state) Commented Jun 10, 2018 at 17:23

3 Answers 3

2

In your mapStateToProps access your state like this:

profilePhoto : state.user.userData ? state.user.userData.photos.primary : ''

and then use profilePhoto as props. This will not throw an error of undefined.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks -- not sure why I didn't think of that. :)
1

In my current application I initialize the redux state with all the data tree that I will use; so that I will unlikely end up with undefineds.

So a solution would be:

const initialState = {
    userData: {
        photos: {
            primary: ""
        }
    }
}

This might look ugly in the first glance but it helps me keep track of what my data will look like, and can be simplified by defining parts of the object individually.

An alternative could be keeping a flag in the redux state like isUserPrimaryPhotoDefined which you would set to true when you are setting the primary variable; so you can use the flag in the ternary. However that might not guarantee getting rid of the possible errors completely.

Comments

0

With ES6 Destructuring Assignment, you can access nested keys from props in a cleaner way.

const { user: { userData: { photos: { primary = ''} = {}} = {}} = {}} = props;
console.log(primary); // prints primary value or '' if not defined

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.