Laura delgado
Laura delgado

Reputation: 362

Replace item inside state array

I've been researching for a while about how to replace the item if it's already exist inside state array but I couldn't find a propitiate solution
https://codesandbox.io/s/4xl24j7r69

import React from 'react';


class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [
        {
          "userId": 1,
          "id": 1,
          "title": "One",
          "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
        },
        {
          "userId": 1,
          "id": 2,
          "title": "Two",
          "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
        },
      ]
    }
  }

  add = () => {
    this.setState(prevState => ({

      data: [...prevState.data,
      {
        "userId": 1,
        "id": 2,
        "title": "Two New",
        "body": "new data",
      }// this item already exist so I want to replace it to new data
      ]
    }))
  };
  render() {
    return (
      <div>
        {this.state.data.map((data) =>
          <ul key={data.id}>
            <li>{data.title}</li>
          </ul>
        )}
        <button onClick={this.add}>Replace</button>
      </div>
    );
  }
}
export default App;

I tried to make like this but it's doesn't work

 add = () => {
    this.setState(prevState => ({
      data: prevState.data.filter(item => this.state.data.indexOf(item.id) !== -1).slice(0, 5), // this not working
      data: [...prevState.data,
      {
        "userId": 1,
        "id": 2,
        "title": "Two New",
        "body": "new data"
      }
      ]
    }))
  };

How can I update the item if it's already exist?

Upvotes: 2

Views: 4598

Answers (2)

FisNaN
FisNaN

Reputation: 2865

You have to create a deep copy recursively and then update the state.

Note:
The slice function will not create deep copy, so you have to create a new object instead. (I use spread operator, there are another choice, such as Object.assign()).

There is the tested code based on your question:

  add = () => {
    this.setState(prevState => {
      const idx = prevState.data.findIndex(item => item.id === 2);
      const nextData = prevState.data.slice();
      const nextItem = { ...nextData[idx] };
      nextItem.title = "Wow! New Two";
      nextData[idx] = nextItem;
      return {
        data: nextData,
      };
    });
  }; 

There is the codesandbox link.

Upvotes: 1

TKoL
TKoL

Reputation: 13902

You could find the item and simply update it with object.assign

let newUser1 = {
        "userId": 1,
        "id": 2,
        "title": "Two New",
        "body": "new data"
      }

this.setState(prevState => {
    let newData = prevState.data;
    let user = newData.find(d => d.id === newUser1.id);
    Object.assign(user, newUser1);
    return {data: newData};
})

Upvotes: 5

Related Questions