2015-03-06 16 views
22

Çoğaltılmış iç içe geçmiş bir bileşene geri arama yapmak istiyorum ve özellikleri etkin bir şekilde iletebildiğim halde, geri çağrının doğru bileşene nasıl bağlanacağını anlayamıyorum. Benim yapısı aşağıdaki gibidir:React.js, geri aramaları alt bileşenlere nasıl iletir?

-OutermostComponent 
    -FirstNestedComponent 
     -SecondNestedComponent 
      -DynamicallyGeneratedListItems 

OutermostComponents yöntemi "onUserInput" olan bir geri arama tetiklemesi gerektiğini tıklandığında, ama bunun yerine almak Liste Öğeleri "Yakalanmayan Hata: Tanımsız bir işlev değil". Sorunun ilk olarak SecondNestedComponent öğesini nasıl oluşturduğum ve geri bildirimi aktardığımdan şüpheleniyorum. Kod şöyle bir şey:

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

Geri aramaları, uygun iç içe geçmiş bileşenlere doğru olarak nasıl bağlarım?

cevap

13

this.onUserInput ürününü FirstNestedComponent'a iletme. Bu nedenle, FirstNestedComponent'da this.props.onUserInput olarak erişmelisiniz. Başvuru için

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

de oluşturduk uygulamasını kontrol edin? – SuperUberDuper

+0

Hayır. Reaksiyonun öğreticisini okursanız, ebeveynlerden çocuk bileşenlerine geri çağrıları iletmek, kursa eşittir. https://facebook.github.io/react/docs/tutorial.html – gregturn

+2

Hayır. Tepki, alt bileşenlere "props" olarak ilettiğiniz yöntemler için "otomatik olarak" şeyleri bağlar. Teknik olarak geri çağrılar hala, tek yönlü veri akışının React'in fikirleri ™ ile uyumludur çünkü bağlam ebeveyntir (çocuk değil) – williamle8300

1

, ben tek yönlü veri akışı paradigma karşı geri aramaları kavramını arn't 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);