ReactJS - 拥有" main"没有它的孩子的组件?

时间:2014-08-15 18:06:30

标签: javascript reactjs

我有一堆组件不能拥有相同的父组件,但我希望他们分享他们的状态。

为了便于讨论,我们可以说顶层组件名为Main,子项都称为Child1Child2等。

我有没有办法让Child1Child2成为Main组件的子项,只有在React意义上 - 所以我可以通过Main属性和状态来自Main组件?

从DOM的角度来看,Child1Child2位于我页面的完全不同的区域,实际上大约有40个。

2 个答案:

答案 0 :(得分:1)

我的一个名为ItemRenderer的组件在mount和每次更新时调用DOM中三个位置的renderComponent(并将一个空div渲染到它的真实容器中):

https://github.com/Khan/perseus/blob/a1811f6b7a/src/item-renderer.jsx#L66-L130

这往往有点难以推理,因为组件没有进入ItemRenderer的父母告诉他们的地方,但是如果那就是你需要它可以工作。

答案 1 :(得分:1)

您可以使用事件发射器,而不是直接调用setState,并且所有实例都可以将有效负载应用于其状态。

我们可以使用mixin来抽象这种行为。

var makeChangeEventMixin = function(emitter){
   return {
       componentDidMount: function(){
           emitter.addListener('change', this.__makeChangeEventMixin_handler_);
       },
       componentWillUnmount: function(){
           emitter.removeListener('change', this.__makeChangeEventMixin_handler_);
       },
       __makeChangeEventMixin_handler_: function(payload){
           this.setState(payload);
       },
       emitStateChange: function(payload){
           emitter.emit('change', payload);
       }
   };
};

然后在我们的代码中,我们将使用EventEmitter(如果您不使用browserify / webpack,则可以使用EventEmitter2

var EventEmitter = require('events').EventEmitter;
var fooEvents = new EventEmitter();

var Counter = React.createClass(){
    mixins: [makeChangeEventMixin(fooEvents)],
    getInitialState: function(){ return {count: 0} },
    render: function(){return <div onClick={this.handleClick}>{this.state.count}</div>},
    handleClick: function(){
        this.emitStateChange({count: this.state.count + 1});
    }
};

如果你有100个计数器,当你点击任何一个计数器时它们都会更新。


这样做的一个限制是初始状态是错误的。您可以通过跟踪makeChangeEventMixin中的状态,将其合并为自己,并使用replaceState而不是setState来解决此问题。这也会更高效。如果你这样做,mixin可以实现一个正确的getInitialState。