Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Whats the best way to update an object in an array in ReactJS?

If you have an array as part of your state, and that array contains objects, whats an easy way to update the state with a change to one of those objects?

Example, modified from the tutorial on react:

var CommentBox = React.createClass({   getInitialState: function() {     return {data: [       { id: 1, author: "john", text: "foo" },       { id: 2, author: "bob", text: "bar" }     ]};   },   handleCommentEdit: function(id, text) {     var existingComment = this.state.data.filter({ function(c) { c.id == id; }).first();     var updatedComments = ??; // not sure how to do this        this.setState({data: updatedComments});   } } 
like image 398
Alex Black Avatar asked Jan 24 '15 01:01

Alex Black


People also ask

How do you update an object in an array in React?

To update an object in an array in React state: Use the map() method to iterate over the array. On each iteration, check if a certain condition is met. Update the object that satisfies the condition and return all other objects as is.

How do you update an object in an array of objects?

To update an object's property in an array of objects, use the map() method to iterate over the array. On each iteration, check if the current object is the one to be updated. If it is, modify the object and return the result, otherwise return the object as is.

How do you update an element in an array?

To update all the elements of an array, call the forEach() method on the array, passing it a function. The function gets called for each element in the array and allows us to update the array's values. Copied! const arr = ['zero', 'one', 'two']; arr.


2 Answers

I quite like doing this with Object.assign rather than the immutability helpers.

handleCommentEdit: function(id, text) {     this.setState({       data: this.state.data.map(el => (el.id === id ? Object.assign({}, el, { text }) : el))     }); } 

I just think this is much more succinct than splice and doesn't require knowing an index or explicitly handling the not found case.

If you are feeling all ES2018, you can also do this with spread instead of Object.assign

this.setState({   data: this.state.data.map(el => (el.id === id ? {...el, text} : el)) }); 
like image 84
Not loved Avatar answered Oct 23 '22 09:10

Not loved


While updating state the key part is to treat it as if it is immutable. Any solution would work fine if you can guarantee it.

Here is my solution using immutability-helper:

jsFiddle:

  var update = require('immutability-helper');    handleCommentEdit: function(id, text) {     var data = this.state.data;     var commentIndex = data.findIndex(function(c) {          return c.id == id;      });      var updatedComment = update(data[commentIndex], {text: {$set: text}});           var newData = update(data, {         $splice: [[commentIndex, 1, updatedComment]]     });     this.setState({data: newData});   }, 

Following questions about state arrays may also help:

  • Correct modification of state arrays in ReactJS
  • what is the preferred way to mutate a React state?
like image 40
nilgun Avatar answered Oct 23 '22 08:10

nilgun