Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: this.state disappears in for loop

How can I carry this into my .map() loop? It seems to disappear. :-(

I'm creating a "dynamic form" where the user can specify multiple lines of input for his form. I want to iterate over all items in state.items[] and build form input fields for them.

E.g the form starts with 'field' and 'autocomplete_from. The user can then click add a new line to get more rows in his form.

102     render: function() {
103       return (
104         <div>
105           {this.state.items.map(function(object, i){
106             return (
107               <div>
109                 <FieldName/>

110                 <strong> State.autocomplete_from:
                            {this.state.autocomplete_from} </strong>
                         //       ^^^ 
                         //   Uncaught TypeError: Cannot read property 'state' of undefined

120                 <button onClick={this.newFieldEntry}>Create a new field</button>
121                 <button onClick={this.saveAndContinue}>Save and Continue</button>
122               </div>
123               );
124           })}
125         </div>
126       );
like image 410
martins Avatar asked Apr 08 '15 14:04

martins


1 Answers

In .map this does not refer to your component., there are several ways how you can solve this issue

  1. Save this to variable

    render: function() {
      var _this = this;
    
      return (
       <div>
         {this.state.items.map(function(object, i){
           return (
             <div>
               <FieldName/>
    
               <strong> State.autocomplete_from:
                 {_this.state.autocomplete_from} </strong>
    
               <button onClick={this.newFieldEntry}>Create a new field</button>
               <button onClick={this.saveAndContinue}>Save and Continue</button>
             </div>
           );
         })}
       </div>
     );
    }
    
  2. Set this for .map callback(if you can't use ES2015 features, this variant is prefered)

    this.state.items.map(function (object, i) {
       // ....
    }, this);
    
  3. use arrow function

    this.state.items.map((object, i) => {
       // ....
    }) 
    
  4. use .bind

    this.state.items.map(function(object, i) {
       // ....
    }.bind(this)) 
    
like image 184
Oleksandr T. Avatar answered Oct 19 '22 09:10

Oleksandr T.