javascript - 防止在 JavaScript 中的代理中多次调用超级方法
问题描述
我围绕一个Component
名为autodispose
. 假设 class A
extendsautodispose(Component)
和 class B
extends A
。mixin 确保A.componentWillUnmount()
无论是否通过代理B.componentWillUnmount()
调用都被调用。super.componentWillUnmount()
(代码在 TypeScript 中,但问题与 JavaScript 有关。)
export function autodispose<
T extends Class<React.Component>
>(Target: T) {
const ObservingComponent = class extends Target {
constructor(...args: any[]) {
super(...args);
// ... mixin setup ...
this.componentWillUnmount = new Proxy(this.componentWillUnmount, {
apply: (target, thisArg, fnArgs) => {
Reflect.apply(target, thisArg, fnArgs);
if (super.componentWillUnmount) {
super.componentWillUnmount();
}
this.__mixinCleanup();
},
});
}
componentWillUnmount() {
if (super.componentWillUnmount) {
super.componentWillUnmount();
}
this.__mixinCleanup();
}
private __mixinCleanup() {
// is a no-op if __mixinCleanup() has already been called
// ...
}
};
}
如果B
调用super.componentWillUnmount()
,则代理将调用A
'componentWillUnmount()
两次——第一次调用Reflect.apply(target, thisArg, fnArgs)
,然后立即调用。我需要一种方法来检测呼叫Reflect.apply()
是否已经呼叫super.componentWillUnmount()
并阻止第二次呼叫。
我考虑过用另一个 Proxy 临时覆盖super.componentWillUnmount
它,它设置一个它被调用的标志,但是,不出所料,你不能覆盖super
的方法。
如果一切都失败了,我可以确保它autodispose
不会在原型链中被调用两次,但这个解决方案会更理想。
解决方案
您不需要(暂时或以其他方式)覆盖B
's super.componentWillUnmount
- 您确实定义了A.prototype.componentWillUnmount
自己!你可以在那里设置标志:
export function autodispose(Target) {
return class ObservingComponent extends Target {
constructor(...args) {
super(...args);
// ... mixin setup ...
this._hasSuperBeenCalled = false;
let original = this.componentWillUnmount;
this.componentWillUnmount = function(...args) {
this._hasSuperBeenCalled = false;
original.apply(this, args);
if (!this._hasSuperBeenCalled)
throw new Error(`Warning: ${this.constructor.name}.componentWillUnmount forgot its super call`);
};
}
componentWillUnmount() {
this._hasSuperBeenCalled = true;
if (super.componentWillUnmount) {
super.componentWillUnmount();
}
// ...mixin cleanup
}
};
}
推荐阅读
- openedge - 以 CSV 格式输出报告的程序
- reactjs - 使用条件时 doc.data() 不是函数
- python - 使用 pandas 从 csv 中删除重复项时出错
- java - LoggerFactory 无法获取Logger
- postgresql - CloudSQL中PostgreSQL的“idle_in_transaction_session_timeout”默认值是多少?
- delphi - 如何在 C++ builder 中实现 Delphi 保护的成员访问技巧?
- php - 如何从 php 中的字节数组中获取图像?
- ruby-on-rails - ActionController::UrlGenerationError 用于设计注册控制器
- c# - 通过流式传输客户端和端通过 HTTP 发送和接收大对象
- java - 如何收集List的属性