3
this.state = {
  array: [1, 2, 3],
  objects: [{ id: 1 }, { id: 2 }, { id: 3 }]
}

How can I change the specific value of an object or array in the state without setStating the whole array/object?

something like

this.setState({ array[2]: 5 })
this.setState({ object[0].id: 0 })
8
  • 2
    There are some options to do it, but basically it's important to understand that this is not a stupid obligation, but it's done in ReactJs by purpose, to mark this object as a changed object to cause new render. Commented Aug 12, 2020 at 8:55
  • 1
    Trying to understand your intention. You sounded like intentionally mutating the object/array? Commented Aug 12, 2020 at 9:45
  • 2
    @Isaac I was meant to copy the whole object/array. Thanks to the community now I know my mistake. Commented Aug 12, 2020 at 9:55
  • 2
    @blueedge: No problem, we learn something new everyday :) Commented Aug 12, 2020 at 10:05
  • 1
    Have you seen this? immerjs.github.io Commented Aug 13, 2020 at 0:53

2 Answers 2

2

You could use a helper function to set an element at an index and return that newly updated array

const array = [1, 2, 3]
const object = [{id: 1}, {id: 2}, {id: 3}]

const setElementAtIndex = (index, value, array) => [
  ...array.slice(0, index),
  value,
  ...array.slice(index + 1)
]

console.log(setElementAtIndex(0, 99, array))
console.log(setElementAtIndex(1, 99, array))
console.log(setElementAtIndex(2, 99, array))
console.log(setElementAtIndex(0, { ...object[0], id: 0 }, object))

this.setState({ array: setElementAtIndex(2, 5, array) })
this.setState({ object: setElementAtIndex(0, { ...object[0], id: 0 }, object) })
Sign up to request clarification or add additional context in comments.

2 Comments

I thought of that initially but I tried finding a more efficient way. I tried finding an inbuilt method for this ( if exist). Is there any better way other than just duplication the whole object
IMO, when working with array and object, we should return a copy (at least shallow one) of the updated to avoid mutation
1

I would use map.

const state = {
     array: [1,2,3],
     objects: [{id: 1}, {id: 2}, {id: 3}]
}

const newArray = state.array.map((v, i) => i === 2 ? 5 : v);
const newObjects = state.objects.map((v, i) => i === 0 ? {...v, id: 0} : v);

console.log(newArray);
console.log(newObjects);

// this.setState({ ...this.state, array: newArray });
// this.setState({ ...this.state, objects: newObjects });

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.