ReactJS -有一个“main”;组件不拥有它的子组件

ReactJS - Have a "main" component that doesn't own it's children?

本文关键字:组件 拥有 有一个 main ReactJS      更新时间:2023-09-26

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

为了方便讨论,我们假设顶级组件称为Main,子组件都称为Child1, Child2等。

我有Child1Child2Main组件的孩子,只有在反应意义上-所以我可以通过Main的属性和状态对他们从Main组件?

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

您可以使用事件发射器而不是直接调用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(你可以使用EventEmitter2,如果你不使用browserify/webpack)

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。

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

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

这有点难以理解,因为组件不会去ItemRenderer的父组件告诉它们去的地方,但如果你需要的话,它可以工作。