2015-01-06 35 views
3

我正在使用react-async和node.js. React-async用於以異步方式使用react.js。要撥打ajax電話,我正在使用super-agentPostList組件是最頂層的父組件。通過其setTopmostParentState方法,可以更改組件的狀態。我想從Comp4調用此方法。此方法的參數將來自使用'超級代理'節點中間件的ajax調用。react.js從深層嵌套的子元素更改最頂層父元素的狀態

如何從Comp4中更改狀態?如果它是父組件然後是子組件問題,那麼狀態更改方法可以很容易地作爲prop傳遞給子組件。但是 幾個嵌套使得將參數從深度嵌套子節點傳遞到頂層父節點變得困難。

代碼段:

var Comp4 = React.createClass({ 

     clickHandler: function() { 

     request.get('/api/prods_find/' + cat_id + '/' + subcat_id, 

      function(resp) { 

      var prods_menu = resp.body; 

* * * //CALL setTopmostParentState of the PostList component with the value prods_menu*** 

      }); 

     }, 
     render: function() { 
     '<div onClick={this.clickHandler}>Target element</div>' 

     } 

    }); 

    var Comp3 = React.createClass({ 

     render: function() { 

     <Comp4> < /Comp4> 

     } 

    }); 

    var Comp2 = React.createClass({ 

     render: function() { 

     <Comp3> < /Comp3> 

     } 

    }); 

    var Comp1 = React.createClass({ 

     render: function() { 

     <Comp2> < /Comp2> 

     } 

    }); 

    var PostList = React.createClass({ 

     mixins: [ReactAsync.Mixin], 

     getInitialStateAsync: function(cb) { 

     request.get('http://localhost:8000/api/posts', function(response) { 

      cb(null, { 
      prods_menu: response.body 
      }); 

     }); 

     }, 
     setTopmostParentState: function(prods_menu) { 

     this.setState({ 

      prods_menu: prods_menu 
     }); 
     }, 
     render: function() { 

     var prods = this.state.prods_menu.prods; 

     var menu = this.state.prods_menu.menu; 

     return (

      <Comp1> < /Comp1> 

     ); 
     } 

    }); 
+1

這個用例[流量](HTTP:// Facebook的。 github.io/flux/)被髮明出來。你想要做的就是觸發組件中的一個動作,通知其他組件(父組件)更新其狀態。 –

+0

@limelight,當節點反應項目處於中間狀態時,任何解決方法都無法實現嗎? –

+2

唯一的另一種方法是將引用傳遞給從最頂層的父元素到最深的子元素,在使用時更改父元素中的狀態。 –

回答

0

在特定情況下,我建議傳承的功能被你最深的子組件調用。

var Comp4 = React.createClass({ 

     clickHandler: function() { 

     request.get('/api/prods_find/' + cat_id + '/' + subcat_id, 

      function(resp) { 

      var prods_menu = resp.body; 
      this.props.updateParentState(prods_menu); 

      }); 

     }, 
     render: function() { 
     '<div onClick={this.clickHandler}>Target element</div>' 

     } 

    }); 

    var Comp3 = React.createClass({ 

     render: function() { 

     < Comp4 {...this.props} > < /Comp4> 

     } 

    }); 

    var Comp2 = React.createClass({ 

     render: function() { 

     < Comp3 {...this.props} > < /Comp3> 

     } 

    }); 

    var Comp1 = React.createClass({ 

     render: function() { 

     < Comp2 {...this.props} > < /Comp2> 

     } 

    }); 

    var PostList = React.createClass({ 

     mixins: [ReactAsync.Mixin], 

     getInitialStateAsync: function(cb) { 

     request.get('http://localhost:8000/api/posts', function(response) { 

      cb(null, { 
      prods_menu: response.body 
      }); 

     }); 

     }, 
     setTopmostParentState: function(prods_menu) { 

     this.setState({ 

      prods_menu: prods_menu 
     }); 
     }, 
     render: function() { 

     var prods = this.state.prods_menu.prods; 

     var menu = this.state.prods_menu.menu; 

     return (

      < Comp1 updateParentState={this.setTopmostParentState} > < /Comp1> 

     ); 
     } 

    }); 

但是正如你所看到的,這很麻煩。這就是Flux創建的原因。使用Flux,您可以將消息發送到包含新數據的商店,商店會通知您的組件,重新渲染它。

您可以瞭解更多關於助焊劑這裏https://facebook.github.io/flux/

0

不是說這是完美的,但在這樣的情況下我使用的PubSub庫組件通信。例如https://www.npmjs.com/package/pubsub-js

在你最上面的組件,你可以這樣做:

var EVENT_NOTIFY_TOPMOST = "EVENT_NOTIFY_TOPMOST"; 
componentDidMount: function() { 
    eventToUnsubscribe = PubSub.subscribe(EVENT_NOTIFY_TOPMOST, function(msg, data){ 
     console.log(data); //logs "world" 
    }); 
} 

componentDidUnmount: function() { 
    //don't forget this 
    PubSub.unsubscribe(eventToUnsubscribe) 
} 

而且在你最深的孩子,你可以這樣做:

PubSub.publish(EVENT_NOTIFY_TOPMOST , "world"); 
相關問題