From 19f86caca695f9ba4417572160a8e9ec0ceeed4c Mon Sep 17 00:00:00 2001 From: nkzawa Date: Sun, 22 Jan 2017 20:38:18 +0900 Subject: [PATCH 1/3] wrap render method created using class properties --- client/patch-react.js | 65 ++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/client/patch-react.js b/client/patch-react.js index b16b8bb9d8fcc..f0712158f43f8 100644 --- a/client/patch-react.js +++ b/client/patch-react.js @@ -17,8 +17,23 @@ export default (handleError = () => {}) => { React.createElement = function (Component, ...rest) { if (typeof Component === 'function') { const { prototype } = Component - if (prototype && prototype.render) { - prototype.render = wrapRender(prototype.render) + + // assumes it's a class component if render method exists. + const isClassComponent = !!(prototype && prototype.render) || + // subclass of React.Component or PureComponent with no render method. + prototype instanceof React.Component || + prototype instanceof React.PureComponent + + if (isClassComponent) { + // There's no render method in prototype + // when it's created with class-properties. + if (prototype.render) { + prototype.render = wrapRender(prototype.render) + } + + // wrap the render method in runtime when the component initialized + // for class-properties. + Component = wrap(Component, withWrapOwnRender) } else { // stateless component Component = wrapRender(Component) @@ -39,24 +54,42 @@ export default (handleError = () => {}) => { } function wrapRender (render) { - if (render.__wrapped) { - return render.__wrapped - } + return wrap(render, withHandleError) + } - const _render = function (...args) { - try { - return render.apply(this, args) - } catch (err) { - handleError(err) - return null - } + function withHandleError (fn, ...args) { + try { + return fn.apply(this, args) + } catch (err) { + handleError(err) + return null } + } - // copy all properties - Object.assign(_render, render) + function withWrapOwnRender (fn, ...args) { + const result = fn.apply(this, args) + if (this.render && this.hasOwnProperty('render')) { + this.render = wrapRender(this.render) + } + return result + } +} - render.__wrapped = _render.__wrapped = _render +function wrap (fn, around) { + if (fn.__wrapped) { + return fn.__wrapped + } - return _render + const _fn = function (...args) { + return around.call(this, fn, ...args) } + + // copy all properties + Object.assign(_fn, fn) + + _fn.prototype = fn.prototype + + _fn.__wrapped = fn.__wrapped = _fn + + return _fn } From a30189b7a44957dd2b5aed4d1869966318a03e0e Mon Sep 17 00:00:00 2001 From: nkzawa Date: Mon, 23 Jan 2017 00:45:31 +0900 Subject: [PATCH 2/3] use Boolean instead of double not-operator --- client/patch-react.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/patch-react.js b/client/patch-react.js index f0712158f43f8..2bb8a2a6fb3b8 100644 --- a/client/patch-react.js +++ b/client/patch-react.js @@ -19,7 +19,7 @@ export default (handleError = () => {}) => { const { prototype } = Component // assumes it's a class component if render method exists. - const isClassComponent = !!(prototype && prototype.render) || + const isClassComponent = Boolean(prototype && prototype.render) || // subclass of React.Component or PureComponent with no render method. prototype instanceof React.Component || prototype instanceof React.PureComponent From 323ac372b9ccd0e2c146b38686804abab812aa96 Mon Sep 17 00:00:00 2001 From: nkzawa Date: Mon, 23 Jan 2017 00:46:49 +0900 Subject: [PATCH 3/3] patch-react: move a comment --- client/patch-react.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/patch-react.js b/client/patch-react.js index 2bb8a2a6fb3b8..810ae7b61f095 100644 --- a/client/patch-react.js +++ b/client/patch-react.js @@ -21,12 +21,12 @@ export default (handleError = () => {}) => { // assumes it's a class component if render method exists. const isClassComponent = Boolean(prototype && prototype.render) || // subclass of React.Component or PureComponent with no render method. + // There's no render method in prototype + // when it's created with class-properties. prototype instanceof React.Component || prototype instanceof React.PureComponent if (isClassComponent) { - // There's no render method in prototype - // when it's created with class-properties. if (prototype.render) { prototype.render = wrapRender(prototype.render) }