扩展 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。
我有一个 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。