2015-04-08 2 views
6

Как переносить this в мой цикл .map()? Кажется, он исчезает. :-(Реакция: this.state исчезает в цикле

Я создаю «динамическую форму», где пользователь может указать несколько строк ввода его формы. Я хочу, чтобы перебрать все элементы в state.items[] и построить поля ввода формы для них.

Например, форма начинается с «поле» и «autocomplete_from. После этого пользователь может нажать добавить новую строку, чтобы получить больше строк в его форме.

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

ответ

10

в .mapэто не относится к компоненте. , существует несколько способов, как вы может решить эту проблему

  1. Сохранить this переменной

    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. Набор this для .map обратного вызова (, если вы не можете использовать ES2015 функции, этот вариант является предпочтительным)

    this.state.items.map(function (object, i) { 
        // .... 
    }, this); 
    
  3. использование arrow function

    this.state.items.map((object, i) => { 
        // .... 
    }) 
    
  4. использование .bind

    this.state.items.map(function(object, i) { 
        // .... 
    }.bind(this)) 
    
+0

Спасибо за подробный ответ[email protected] omar-elawady, вы тоже верны, но я буду отмечать это как принятое, поскольку это более подробно. :-) – martins

0

второй аргумент для итерационного метода, такие как map и filter является this объект

так что вы можете использовать его следующим образом:

this.state.items.map(yourfunction,this)

+0

Должен обновить вызов карты только одной запятой. Большинство людей должны понять, что это вызовет ошибку (так как это должен быть второй аргумент), но, вероятно, это хорошо, если кто-то приходит, а кто нет. – chaseadamsio

+1

Вы правы. –

0

Когда вы вызываете функцию. Этот параметр установлен на глобальный объект, если только это метод-член, который вы вызываете, или вы вызываете либо .call, либо .apply, которого вы не можете в своем случае.

или другими словами, вы не можете закрыть более this, однако вы можете приблизиться к стандартной переменной, которой вы присвоили это. Таким образом, в общем, если у вас есть функция вложены в другой Funtion, и вы хотите refere к этому сделать:

function outer(){ 
    var _this = this; 
    someThingThatAcceptsACallback(function(){ 
     console.log(_this.state); 
    } 
} 
0

Если вы используете Babel или другой современный EcmaScript6-> JS5 компилятор, вы можете использовать более простой синтаксис сохраняя контекст внешнего контекста:

{ 
    this.state.items.map((object, i) => { 
     return (<div> 
       <strong> State.autocomplete_from: 
        {this.state.autocomplete_from} 
       </strong> 
       /*.... your code ...*/ </div>); 
    }); 
} 

используя синтаксис функции стрелка, то this контекст связан автоматически в содержащемуся функции, так что вы можете использовать this, как вы уже были и вам не нужно делать ничего особенного в вашем коде.

Смежные вопросы