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

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.