2017-09-07 1 views
2

Je suis nouveau à Réagir et c'est une question très noob, mais je ne comprends pas pourquoi cela ne fonctionne pas. J'essaye de construire une liste simple de todo.passer un événement à un composant enfant dans React

Mon TodoList.js Component ressemble à ceci:

import React, {Component} from 'react'; 
import TodoItem from './TodoItem'; 

    export default class TodoList extends Component{ 
     constructor(props){ 
     super(props); 
     this.state = { 
      todos:[ 
      { 
       title:"todo1" 
      }, 
      { 
       title:"todo3" 
      }, 
      { 
       title:"todo2" 
      } 
      ] 
     } 

     } 

     handleRemove(idx){ 
     alert('works'); 
     } 

     render(){ 
     var todos = this.state.todos.map(function(t,idx){ 
      return(<TodoItem 
        remove={this.handleRemove.bind(this,idx)} 
        title={t.title} 
      />) 
     }) 

     return (
      <div> 
      <h1>To do</h1> 
      <div>{todos}</div> 
      </div> 
     ) 
     } 
    } 

Mon enfant Component ressemble à ceci:

import React, {Component} from 'react'; 

    export default class TodoItem extends Component{ 
     render(){ 
     return (
      <div>{this.props.title} 
      <button onClick={this.props.remove}>X</button> 
      </div> 
     ) 
     } 
    } 

Mais je reçois un TypeError avec "Impossible de lire la propriété 'handleRemove' undefined". Je me demande pourquoi dans la fonction de carte {this} est indéfini? J'ai essayé de placer ce this.handleRemove = this.handleRemove.bind(this) dans le constructeur.

N'a rien changé. Ne devrait-on pas définir this à l'intérieur du .map()?

Répondre

2

Vous devez mettre this comme second argument

Si un paramètre thisArg est fourni à la carte, il sera utilisé comme cette valeur de rappel . Sinon, la valeur indéfinie sera utilisée comme sa valeur. La valeur que l'on peut finalement observer par rappel est déterminée selon les règles habituelles pour déterminer le ceci vu par une fonction.

sur map:

render(){ 
     var todos = this.state.todos.map(function(t,idx){ 
      return(<TodoItem 
        remove={this.handleRemove.bind(this,idx)} 
        title={t.title} 
      />) 
     }, this) 

     return (
      <div> 
      <h1>To do</h1> 
      <div>{todos}</div> 
      </div> 
     ) 
     } 
    } 

Vous pouvez également utiliser un ES6 arrow function pour préserver automatiquement le this contexte actuel:

var todos = this.state.todos.map((t,idx) => { 
    return(<TodoItem 
    remove={this.handleRemove.bind(this,idx)} 
    title={t.title} 
    />) 
}) 
+0

ahhhhhhh, merci! comment aurais-je pu être si aveugle! Merci ! – Tom