grazdev
grazdev

Reputation: 1272

How to update only one value in nested array of Redux state?

Consider the following state:

const initState = {
    id: {
        data: null, 
        isFetching: false, 
        fetchingError: null
    },  
    bookmarks: {
        IDs: {
            news: [], 
            opps: [],
            posts: []           
        },
        data: {
            news: [], 
            opps: [],
            posts: []
        },      
        isFetching: false, 
        fetchingError: null
    },
    role: null,
    membership: null,   
}

How do I update just the posts array in the ÌDs array in the bookmarks array? I tried this:

case 'SET_USER_BOOKMARKED_POSTS':
    return {
        ...state, 
        bookmarks: {
            IDs: {
                posts: action.payload
            }
        }
    }

But when I log the state to the console the IDs array then only contains posts, while the opps and news arrays are not there anymore.

Upvotes: 1

Views: 223

Answers (3)

Sterling Archer
Sterling Archer

Reputation: 22405

The way we do it is a non-mutative method using Object.assign to basically point and update a field in the redux state. Something like:

return Object.assign({}, state.bookmarks, {
    IDs: action.payload,
});

This will make sure you're not mutating the state, and returns the new bookmarks. You can adjust this to return the entire state if you'd like, it depends on if you need the other data on the update.

Upvotes: 0

ilsotov
ilsotov

Reputation: 162

You need to destruct all inner structure:

case 'SET_USER_BOOKMARKED_POSTS':
    return {
        ...state, 
        bookmarks: {
            ...state.bookmarks,
            IDs: {
                ...state.bookmarks.IDs,
                posts: action.payload
            }
        }
    }

But this is not very convinient, better use lodash merge

Upvotes: 2

Abhishek Gupta
Abhishek Gupta

Reputation: 1337

You need use the spread operator for state.bookmarks.IDs also as when specifies keys after the spread operator, the value for the keys are overwritten.

case 'SET_USER_BOOKMARKED_POSTS':
return {
    ...state, 
    bookmarks: {
        ...state.bookmarks
        IDs: {
            ...state.bookmarks.IDs,
            posts: action.payload
        },   
    }
}

Upvotes: 2

Related Questions