diff --git a/lib/c-promise.js b/lib/c-promise.js index e3b6605..2b14c57 100644 --- a/lib/c-promise.js +++ b/lib/c-promise.js @@ -2284,7 +2284,9 @@ const reactProtoMethods= { shouldComponentUpdate: true, componentWillUnmount: true, getSnapshotBeforeUpdate: true, - componentDidUpdate: true + componentDidUpdate: true, + componentDidCatch: true, + componentWillReceiveProps: true } const decorators = { @@ -2414,77 +2416,74 @@ const decorators = { options) || {}; const descriptors= {}; - let propsChanged; - const bindAll= bindMethods && bindListeners; const bind= bindMethods || bindListeners; - return { kind: 'class', finisher(constructor) { const {prototype} = constructor; - const decorate= (prop)=>{ - const method = prototype[prop]; - if (typeof method !== 'function') return; - - let decoratedMethod, preparedMethod; - + const decorate= (prop, method)=>{ + let originalMethod = method; const isComponentWillUnmount = prop === 'componentWillUnmount'; const isComponentDidMount = prop === 'componentDidMount'; - if (isGeneratorFunction(method)) { - preparedMethod = context.promisify(method, { - scopeArg: isComponentDidMount || isComponentWillUnmount - }); - } else if (isComponentWillUnmount || context.isPromisifiedFn(method)) { - preparedMethod = method; - } - - if(preparedMethod) { + const decorateAsyncMethod = (method) => { if (isComponentWillUnmount) { - decoratedMethod = function () { + return function () { cancelContext(this, '', E_REASON_UNMOUNTED); - return preparedMethod.apply(this, arguments); + return method.apply(this, arguments); } - } else if (isComponentDidMount || subscribeAll) { - decoratedMethod = function () { - return preparedMethod + } else if (subscribeAll || isComponentDidMount) { + return function () { + return method .apply(this, arguments) .listen(ensureContextSignal(this, '', true)) } } + return method; } - if (bind && !reactProtoMethods[prop] && bindAll || - (eventHandlerRE.test(prop) ? bindListeners : bindMethods)) { - const targetFn = decoratedMethod || method; + const bindLazily= (method)=>{ descriptors[prop] = { get() { const context= this; return function lazilyBoundListener() { - return targetFn.apply(isContextDefined(this) ? this : context || this, arguments); + return method.apply(isContextDefined(this) ? this : context || this, arguments); } }, configurable: true } - propsChanged = true + } + + if (isGeneratorFunction(method)) { + method = decorateAsyncMethod(context.promisify(method, { + scopeArg: isComponentDidMount || isComponentWillUnmount + })); + }else if (context.isPromisifiedFn(method)) { + method= decorateAsyncMethod(method); + } + + if (bind && !reactProtoMethods[prop] && (bindAll || + (eventHandlerRE.test(prop) ? bindListeners : bindMethods))) { + bindLazily(method); return; } - if(decoratedMethod) { + if (method !== originalMethod) { descriptors[prop] = { - value: decoratedMethod, + value: method, configurable: true } - propsChanged = true } }; Object.getOwnPropertyNames(prototype).forEach(prop => { if (prop === 'constructor' || prop === 'render') return; - decorate(prop); + const value= prototype[prop]; + if (typeof value !== 'function') return; + decorate(prop, value); }); if(!('componentWillUnmount' in prototype)){ @@ -2494,10 +2493,9 @@ const decorators = { }, configurable: true }; - propsChanged = true; } - propsChanged && Object.defineProperties(prototype, descriptors); + Object.defineProperties(prototype, descriptors); return constructor; } diff --git a/playground/src/TestComponent.js b/playground/src/TestComponent.js index c1d4165..f4e54c0 100644 --- a/playground/src/TestComponent.js +++ b/playground/src/TestComponent.js @@ -37,10 +37,6 @@ class TestComponent extends ProtoComponent{ } } - *componentWillUnmount() { - console.log('unmount'); - } - render() { return
useAsyncEffect demo:
@@ -49,7 +45,7 @@ class TestComponent extends ProtoComponent{ className="btn btn-success" onClick={this.fetch} > - Fetch random character info + Fetch data