扩展 React 组件的更好方法

Better way of extending React components

我有一个 none UI 原版 javascript 相关插件,名为 SignalR.EventAggregatorProxy。它是一个服务器 - 客户端 pub/sub 库。

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

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 否则我的库将无法取消订阅组件并且服务器端事件将继续流入。(另外这将是内存泄漏)。有更好的方法吗?

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

有什么想法吗?

您可以使用某种类型的提供程序,用户将用它来包装他的根组件,类似于 react-router 或 redux 正在做的事情。并且还提供一个包装器组件来进行订阅。

这是一个例子:

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

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

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

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

为了让组件在 props 中获得 subscribe,用户可以像这样用您的包装器组件包装他的组件:

<SubscribeProvider>
  <MyComponent/>
</SubscribeProvider>

或使用您也实现的 withSubscribe 功能。

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