martins martins - 2 months ago 11
React JSX Question

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

Answer

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