react.js从深层嵌套的子级更改最顶层父元素的状态

时间:2015-01-06 00:06:02

标签: node.js reactjs react-async

我正在使用react-async和node.js. React-async用于以异步方式使用react.js。要进行ajax调用,我使用的是super-agentPostList组件是最顶层的父组件。通过其setTopmostParentState方法,可以更改组件的状态。我想从Comp4调用此方法。此方法的参数将来自使用' super-agent'的ajax调用。节点中间件。

如何从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>

        );
      }

    });

2 个答案:

答案 0 :(得分: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,您可以将消息发送到包含新数据的Store,并且Store会通知您的Component,重新呈现它。

您可以在https://facebook.github.io/flux/

了解有关Flux的更多信息

答案 1 :(得分: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");