import * as React from "react";
import { observer } from 'mobx-react';
import { decorator_compatibility } from './utils';
/**
* Method decorator to make render methods MobX Observers.
* Apply to a method that returns a React Element:
*
* ```jsx
* @observerMethod
* renderItem({ observable }) {
* return
{observable.value}
* }
* ```
*/
export const observerMethod = decorator_compatibility({
legacy(target, key, descriptor?) {
let fn = descriptor.value;
if (typeof fn !== 'function') {
throw new TypeError(`@observerMethod decorator can only be applied to methods not: ${typeof fn}`);
}
// In IE11 calling Object.defineProperty has a side-effect of evaluating the
// getter for the property which is being replaced. This causes infinite
// recursion and an "Out of stack space" error.
let definingProperty = false;
return {
configurable: true,
get() {
// eslint-disable-next-line no-prototype-builtins
if (definingProperty || this === target.prototype || this.hasOwnProperty(key) ||
typeof fn !== 'function') {
return fn;
}
const boundFn = fn.bind(this);
const ObserverComponent = observer(boundFn);
ObserverComponent.displayName = `ObserverMethod(${fn.name})`;
const wrappedFn = (props) => React.createElement(ObserverComponent, props);
definingProperty = true;
Object.defineProperty(this, key, {
configurable: true,
get() {
return wrappedFn;
},
set(value) {
fn = value;
delete this[key];
}
});
definingProperty = false;
return wrappedFn;
},
set(value) {
fn = value;
}
};
},
stage3(value, context) {
if (context.kind != "method") throw new TypeError(`@observerMethod decorator can only be applied to methods not: ${context.kind}`);
context.addInitializer(function () {
const f = this[context.name];
const boundFn = f.bind(this);
const ObserverComponent = observer(boundFn);
ObserverComponent.displayName = `ObserverMethod(${context.name})`;
const wrappedFn = (props) => React.createElement(ObserverComponent, props);
this[context.name] = wrappedFn;
})
},
})
/**
* @deprecated
*/
export function observerMethod1(target, key, descriptor) {
let fn = descriptor.value;
if (typeof fn !== 'function') {
throw new TypeError(`@observerMethod decorator can only be applied to methods not: ${typeof fn}`);
}
// In IE11 calling Object.defineProperty has a side-effect of evaluating the
// getter for the property which is being replaced. This causes infinite
// recursion and an "Out of stack space" error.
let definingProperty = false;
return {
configurable: true,
get() {
// eslint-disable-next-line no-prototype-builtins
if (definingProperty || this === target.prototype || this.hasOwnProperty(key) ||
typeof fn !== 'function') {
return fn;
}
const boundFn = fn.bind(this);
const ObserverComponent = observer(boundFn);
ObserverComponent.displayName = `ObserverMethod(${fn.name})`;
const wrappedFn = (props) => React.createElement(ObserverComponent, props);
definingProperty = true;
Object.defineProperty(this, key, {
configurable: true,
get() {
return wrappedFn;
},
set(value) {
fn = value;
delete this[key];
}
});
definingProperty = false;
return wrappedFn;
},
set(value) {
fn = value;
}
};
}