扩展React组件的更好方法

时间:2019-03-06 12:21:08

标签: reactjs react-component

我在香草JavaScript中有一个与UI没有相关的插件,称为SignalR.EventAggregatorProxy。它是服务器-客户端发布/订阅库。

我已经有一个Vue插件,现在考虑实现React插件。我需要一些有关组件的终生知识。一种方法是扩展React.Component,并让lib的用户使用此组件而不是原始组件。

class MyEvent
{
   constructor(message) 
   {
       this.message = message;
   }
}

class SignalREventAggregatorComponent extends React.Component {
     subscribe(event, handler, constraint) {
         setTimeout(() => handler(new MyEvent("This comes from backend")), 1000); //signalR.eventAggregator.subscribe(event, handler, this, constraint)
     }

     publish(event) {
         //signalR.eventAggregator.publish(event);
     }

     componentWillUnmount() {
         //signalR.eventAggregator.unsubscribe(this);
     }
}

class TestComponent  extends SignalREventAggregatorComponent  {
  componentDidMount() { 
    this.subscribe(MyEvent, this.onEvent);
  }

  componentWillUnmount() {
     //Doing some teardown in TestComponent 
     super.componentWillUnmount(); // This is paramount to call
  }

  onEvent(e) {
     console.log(e);
  }

  render() {
    return (
      <div>
      </div>
    );
  }
}

这有点脆弱,首先强迫用户扩展这样的特定组件并不好。他们可能已经有另一个第三方库已经扩展,等等。其次是脆弱的。用户需要调用super.componentWillUnmount,否则我的库将无法取消订阅该组件,并且服务器端事件将继续流式传输。(此外,这将导致内存泄漏)。有更好的方法吗?

我需要知道组件何时死亡,而且我必须知道其上下文(基本上是此关键字)。此外,该组件还需要一种在插件上调用方法以订阅和发布事件的好方法。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您可以创建HOC而不是继承,并将其与TestComponent一起使用! 检出this example

答案 1 :(得分:0)

您可以使用某种提供程序,用户可以使用该提供程序包装其根组件,类似于react-router或redux所做的事情。并且还提供了一个包装器组件,可以进行订阅。

这是一个例子:

渲染根组件,您的提供商将subscribe函数添加到  应用程序上下文。这是可选的,具体取决于您是否要在应用中保留唯一状态:

render() {
  <YourProvider>
    <App/>
  </YourProvider>
}

想要监听事件的组件的示例:

componentDidMount() {
  this.props.subscribe(MyEvent, this.onEvent);
}

为了使组件在subscribe中获得props,用户可以使用包装器组件包装其组件,如下所示:

<SubscribeProvider>
  <MyComponent/>
</SubscribeProvider>

或使用您也实现的withSubscribe函数。