Reputation: 362
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
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
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