Я написал миксин декоратора TypeScript / JavaScript вокруг React Component
под названием autodispose
. Предположим, что класс A
расширяет autodispose(Component)
, а класс B
расширяет A
. Миксин гарантирует, что 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
s componentWillUnmount()
дважды - сначала по Reflect.apply(target, thisArg, fnArgs)
, а затем сразу после этого. Мне нужен способ определить, вызвал ли вызов Reflect.apply()
уже super.componentWillUnmount()
, и предотвратить второй вызов.
Я рассмотрел возможность временного переопределения super.componentWillUnmount
другим прокси-сервером, который устанавливает флаг, который он был вызван, но, что неудивительно, вы не можете переопределить методы super
.
Если ничего не помогает, я могу просто убедиться, что autodispose
не вызывается в цепочке прототипов дважды, но это решение было бы более идеальным.