Asked  7 Months ago    Answers:  5   Viewed   38 times

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});
  }
}

 Answers

38

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?
Tuesday, June 1, 2021
 
ManojGeek
answered 7 Months ago
14

In JSX, lower-case tag names are considered to be HTML tags. However, lower-case tag names with a dot (property accessor) aren't.

See HTML tags vs React Components.

  • <component /> compiles to React.createElement('component') (html tag)
  • <Component /> compiles to React.createElement(Component)
  • <obj.component /> compiles to React.createElement(obj.component)
Tuesday, June 1, 2021
 
ranhan
answered 7 Months ago
76

I figured it out - the tutorial is missing two things:

  1. The script inclusion should be done thus, with a type declaration:

    <script type="text/jsx" src="/Scripts/Tutorial.jsx"></script>

  2. The JSX transformer needs to be included:

    <script src="http://fb.me/JSXTransformer-0.12.2.js"></script>

So the full HTML output by the Razor view should look like this:

<!DOCTYPE html>
<html>
  <head>
    <title>Hello React</title>
  </head>
  <body>
    <div id="content"></div>
    <script src="http://fb.me/react-0.12.2.js"></script>
    <script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
    <script type="text/jsx" src="/Scripts/Tutorial.jsx"></script>
  </body>
</html>

Looks like they need to update their tutorial.

Update:

Commenter @DanielLoNigro added this helpful tip:

Actually if you're using ReactJS.NET, you don't need to use the client-side JSXTransformer. Just ensure that the JSX handler is configured in your Web.config file (there should be a handler for .jsx).

Monday, August 16, 2021
 
Robert C. Barth
answered 4 Months ago
42

Set a tag on the imageView when you create it:

 [image viewSetTag: uniqueIntValue];

Then when you want to grab the view use:

UIView* recoveredImageView = [cell viewWithTag uniqueIntValue];
Thursday, September 2, 2021
 
Georges Dupret
answered 3 Months ago
91

You can get do a cloning of the state object using spread operator and then find the index of object in array with a given id using findIndex method Modify the object and set the state.

constructor(props) {
  super(props);
  this.state = {
    data: [{
        id: 0,
        title: 'Buy a',
        status: 0, // 0 = todo, 1 = done
      },
      {
        id: 1,
        title: 'Buy b',
        status: 0,
      },
      {
        id: 2,
        title: 'Buy c',
        status: 0,
      }
    ]
  };
  this.onTitleChange = this.onTitleChange.bind(this);
}
onTitleChange(id, title) {
   var data = [...this.state.data];
   var index = data.findIndex(obj => obj.id === id);
   data[index].title = title;
   this.setState({data});
}
Wednesday, November 10, 2021
 
Yoshi
answered 3 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share