28

Ok, so I'm so frustrated finding the right solution so I'm posting the problem here. Giving an answer would help me a lot, coz I'm stuck!

the state tree looks like this

this.state = {
      itemList : [{
                    _id : 1234,
                   description : 'This the description',
                   amount : 100
                    }, {
                    _id : 1234,
                   description : 'This the description',
                   amount : 100
                    }],
     }

The problems are :

  1. can not update any specific key in the Object of the array according to the _id
  2. The previous state should remain intact

4 Answers 4

59

answered March 25 2018

This is how you would use setState and prevstate to update a certain attribute of an object in your data structure.

this.setState(prevState => ({
    itemList: prevState.itemList.map(
    obj => (obj._id === 1234 ? Object.assign(obj, { description: "New Description" }) : obj)
  )
}));

answered Dec 12 2019 (REACT HOOKS)

import React, { useState } from 'react';
const App = () => {
  const [data, setData] = useState([
    {
      username: '141451',
      password: 'password',
      favoriteFood: 'pizza',
    },
    {
      username: '15151',
      password: '91jf7jn38f8jn3',
      favoriteFood: 'beans'
    }
  ]);
  return (
    <div>
    {data.map(user => {
      return (
        <div onClick={() => {
          setData([...data].map(object => {
            if(object.username === user.username) {
              return {
                ...object,
                favoriteFood: 'Potatos',
                someNewRandomAttribute: 'X'
              }
            }
            else return object;
          }))
        }}>
        {JSON.stringify(user) + '\n'}
        </div>
      )
    })}
    </div>
  )
}
Sign up to request clarification or add additional context in comments.

3 Comments

@Omar I need to update the whole objects in the array ??
Then just do const updatedValues = array.map(item => { return { ...item, updatedKey: ‘value’ } })
Object.assign(obj mutates the current state object which is an anti-pattern in React. Object.assign({}, obj would correctly create a new object.
1

to update state constructed like this you will have to find index of element you want to update, copy the array and change found index.

it's easier and more readable if you keep list of records as object, with id as a key and record as a value.

2 Comments

Then how to iterate all the objects ?
if you're using lodash or ramda in your app, you can use that, or you can use Object.keys(). i usually use redux to keep data like this and use reselect, so my selectors return arrays
-3

The only way to do this will be to copy itemList, modify it, and set the state to it.

update() {
   let itemList = this.state.itemList.slice();
   //update it
   this.setState({ itemList });
}

5 Comments

let itemList = this.state.itemList;. If you modify itemList after this, you are mutating the state.
Not when you slice it.
@DragoşPaulMarinescu you're wrong slice creates a copy
Since the post was edited, it's obvious my comment referred to the initial code.
@DragoşPaulMarinescu didnt see the edit, did just now though
-3

Best way to update data into an array of objects

onChange={ (e) => this.setState({formData: { ...this.state.formData, 'plan_id': 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.