Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: Updating state when state is an array of objects

I have an array of objects in state:

this.state = {   items: [     {id: 1, someattr: "a string", anotherattr: ""},     {id: 2, someattr: "another string", anotherattr: ""},     {id: 3, someattr: "a string", anotherattr: ""},   ] } 

I need to be able to search the items array based on the id property and then update the objects attributes.

I can get the object by filtering or finding on the array using the id param.

What I'm having trouble with is then updating the array and then subsequently updating state without mutation.

//make sure we're not mutating state directly by using object assign const items = Object.assign({}, this.state.items); const match = items.find((item) => item.id === id); 

At this point I have a matching object and can update it's properties using object spread:

const matchUpdated = { ...match, someattr: 'a new value'}; 

My question is how do i then update the state with matchUpdated so that it overwrites the object returned by the initial find operation?

like image 600
Mike Rifgin Avatar asked Jun 06 '16 16:06

Mike Rifgin


People also ask

Can state in React be an array?

Arrays in React State export default App; As mentioned, the initial array state is done in the React component's constructor and afterward used within the render() method to display it. Every time the state changes, the render method will run again and display the correct state in your browser.

What is the proper way to update the state in React?

To update our state, we use this. setState() and pass in an object. This object will get merged with the current state.

Why we should not directly update state in React?

One should never update the state directly because of the following reasons: If you update it directly, calling the setState() afterward may just replace the update you made. When you directly update the state, it does not change this.

How do you get data from array of objects in React JS?

To render an array of objects in react with JSX we need to use Array. map() to transform the object into something react can make use of because you cannot directly render an object into React. Instead, by using Array.


1 Answers

Your update function would look like this

updateItem(id, itemAttributes) {   var index = this.state.items.findIndex(x=> x.id === id);   if (index === -1)     // handle error   else     this.setState({       items: [          ...this.state.items.slice(0,index),          Object.assign({}, this.state.items[index], itemAttributes),          ...this.state.items.slice(index+1)       ]     }); } 

And you use it like this

this.updateItem(2, {someattr: 'a new value'}); 

Gross right?


You're going to have a big headache in general if you continue to build a complex application in this manner. I would recommend you look into redux or some other Flux implementation that is better suited for solving these problems.

Redux uses a concept of state reducers which each work on a specific slice of the state of your application. That way you don't have to manually dig through your entire state each time you want to affect a deep change.

The creator of Redux, Dan Abramov, has made two video courses available online for free. Dan is an excellent teacher and I felt comfortable with the Redux pattern after spending just one afternoon with it.

  • https://egghead.io/courses/getting-started-with-redux
  • https://egghead.io/courses/building-react-applications-with-idiomatic-redux
like image 109
Mulan Avatar answered Sep 19 '22 15:09

Mulan