14

I have the following object. This object gets assigned a new value when the user clicks on a button.

state = {
  title: '',
  id: '',
  imageId: '',
  boarding: {
    id: '',
    test: '',
    work: {
      title: '',
      id: ''
    }
  }
}

My updated object looks like:

state = {
  title: 'My img',
  id: '1234',
  imageId: '5678-232e',
  boarding: {
    id: '0980-erf2',
    title: 'hey there',
    work: {
      title: 'my work title',
      id: '456-rt3'
    }
  }
}

Now I want to update just work object inside state and keep everything the same. I was using Object.assign() when the object was not nested but confused for nesting.

Object.assign({}, state, { work: action.work });

My action.work has the entire work object but now I want to set that to boarding but this replaces everything that is in boarding which is not what I want.

4 Answers 4

31

You should manually merge deep object properties, try following:

Object.assign({}, state, { 
  boarding: Object.assign({}, state.boarding, {
    work: action.work
  }
});

or with spread operator

{
  ...state,
  boarding: {
    ...state.boarding,
    work: action.work
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

could you please explain the role of spread operator in your example and how that is different from your first merge deep prop?
@fscore I've just found very nice link on this topic, I believe you would like it!
@dhilt: the example with spread operator is a good one, but it should be assigned to state or to a constant or variable. The way how it's posted is causing an error and confusing it user would use it just as it is I would give the example such as: state = { ...state, boarding: { ...state.boarding, work: action.work } }
1

If merging them manually as @dhilt suggested is not an option, take a look at lodash's merge.

You can use mergeWith if you want to customise the merge behaviour, e.g. merge arrays instead of overriding.

Comments

0

You can use Object.assign to update nested objects, for example:

Object.assign(state.boarding, { work: action.work })

This will update the state in place with the new work properties.

3 Comments

This will NOT return state, but state.boarding.
I didn't say it would return it, I said it would update state in place.
Actually, I was wrong. This doesn't even compile in most cases. And even when it does, it has zero effect. Please read the docs: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… I'm sorry, but you should delete this answer as it's completely wrong. I'm going to downvote it otherwise.
0

> Use JavaScript spread operator:

{ ...user, staff_information: { nid: e.target.value }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.