2015-03-06 20 views
22

Ich möchte einen Rückruf an eine doppelt verschachtelte Komponente übergeben, und während ich die Eigenschaften effektiv übergeben kann, kann ich nicht herausfinden, wie Sie den Rückruf an die richtige Komponente binden, so dass es ausgelöst wird. Meine Struktur sieht wie folgt aus:React.js wie Rückrufe an untergeordnete Komponenten übergeben werden?

-OutermostComponent 
    -FirstNestedComponent 
     -SecondNestedComponent 
      -DynamicallyGeneratedListItems 

Die Listenelemente, wenn darauf geklickt sollte einen Rückruf auslösen, die die OutermostComponents Methode „onUserInput“ ist, sondern ich „nicht erfasste Fehler: Nicht definiert ist keine Funktion“. Ich vermute, dass das Problem darin besteht, wie ich die SecondNestedComponent in die erste und die Callback-Funktion übergebe. Der Code sieht etwa so aus:

var OutermostComponent = React.createClass({ 
    onUserInput: //my function, 
    render: function() { 
     return (
      <div> 
      //other components 
       <FirstNestedComponent 
        onUserInput={this.onUserInput} 
       /> 
      </div> 
     ); 
    } 
}); 

var FirstNestedComponent = React.createClass({ 
    render: function() { 
     return (
      <div> 
      //other components 
       <SecondNestedComponent 
        onUserInput={this.onUserInput} 
       /> 
      </div> 
     ); 
    } 
}); 
var SecondNestedComponent = React.createClass({ 
    render: function() { 
     var items = []; 
     this.props.someprop.forEach(function(myprop) { 
      items.push(<DynamicallyGeneratedListItems myprop={myprop} onUserInput={this.props.onUserInput}/>);}, this); 
     return (
      <ul> 
       {items} 
      </ul> 
     ); 
    } 
}); 

Wie kann ich richtig Rückrufe an den entsprechenden verschachtelten Komponenten binden?

Antwort

13

Sie übergeben this.onUserInput als eine Eigenschaft an FirstNestedComponent. Daher sollten Sie darauf unter FirstNestedComponent als this.props.onUserInput zugreifen.

var FirstNestedComponent = React.createClass({ 
    render: function() { 
     return (
      <div> 
       <SecondNestedComponent 
        onUserInput={this.props.onUserInput} 
       /> 
      </div> 
     ); 
    } 
}); 
+0

arn't das Konzept der Rückrufe gegen den unidirektionalen Datenfluß Paradigma geschaffen haben? – SuperUberDuper

+0

Nein. Wenn Sie das Lernprogramm von react gelesen haben, ist das Übergeben von Rückrufen von Eltern zu Kind-Komponenten gleichbedeutend mit dem Kurs. https://facebook.github.io/react/docs/tutorial.html – gregturn

+2

Nein Mann. Reagieren bindet Zeug "automatisch" für Methoden, die Sie als "Requisiten" an untergeordnete Komponenten übergeben. Technisch gesehen entsprechen Callbacks immer noch den Reacts Ideen des unidirektionalen Datenflusses, da der Kontext der Elternteil ist (nicht da Kind) – williamle8300

1

Für Ihre Referenz, überprüfen Sie bitte die Umsetzung ich jsfiddle.net/kb3gN/12007

function ListenersService(){ 
    var listeners = {}; 
    this.addListener = function(callback){ 
     var id; 
     if(typeof callback === 'function'){ 
      id = Math.random().toString(36).slice(2); 
      listeners[id] = callback; 
     } 
     return id; 
    } 
    this.removeListener = function(id){ 
     if(listeners[id]){ 
      delete listeners[id]; 
      return true; 
     } 
     return false; 
    } 
    this.notifyListeners = function(data){ 
     for (var id in listeners) { 
      if(listeners.hasOwnProperty(id)){ 
      listeners[id](data); 
      } 
     } 
    } 
} 

function DataService(ListenersService){ 
    var Data = { value: 1 }; 
    var self = this; 

    var listenersService = new ListenersService(); 
    this.addListener = listenersService.addListener; 
    this.removeListener = listenersService.removeListener; 
    this.getData = function(){ 
     return Data; 
    } 

    setInterval(function(){ 
     Data.value++; 
     listenersService.notifyListeners(Data); 
    }, 1000); 
} 
var dataSevice = new DataService(ListenersService); 

var World = React.createClass({ 
    render: function() { 
     return <strong>{this.props.data.value}</strong>; 
    } 
}); 

var Hello = React.createClass({ 
    getInitialState: function() { 
     return { 
      data: this.props.dataService.getData() 
     }; 
    }, 
    componentDidMount: function() { 
     this.props.dataService.addListener(this.updateHandler) 
    }, 
    updateHandler: function(data) { 
     this.setState({ 
      data: data 
     }); 
    }, 
    render: function() { 
     return (
      <div> 
       Value: <World data={this.state.data} /> 
      </div> 
     ); 
    } 
}); 

React.renderComponent(<Hello dataService={dataSevice} />, document.body); 
Verwandte Themen