From 33f237609df0312545261fd26ac4f6c567900b9f Mon Sep 17 00:00:00 2001 From: Anton Korzunov Date: Thu, 8 Mar 2018 23:32:30 +1100 Subject: [PATCH] break render recursion, fix #882 --- src/proxy/createClassProxy.js | 13 ++++++++++--- src/reconciler/hotReplacementRender.js | 6 +++++- test/proxy/consistency.test.js | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/proxy/createClassProxy.js b/src/proxy/createClassProxy.js index 1b4f9dde7..5d170baae 100644 --- a/src/proxy/createClassProxy.js +++ b/src/proxy/createClassProxy.js @@ -27,6 +27,7 @@ const blackListedClassMembers = [ 'componentDidMount', 'componentWillReceiveProps', 'componentWillUnmount', + 'hotComponentRender', 'getInitialState', 'getDefaultProps', @@ -135,10 +136,10 @@ function createClassProxy(InitialComponent, proxyKey, options) { }, ) - function proxiedRender() { - proxiedUpdate.call(this) + function hotComponentRender() { + // repeating subrender call to keep RENDERED_GENERATION up to date renderOptions.componentWillRender(this) - + proxiedUpdate.call(this) let result // We need to use hasOwnProperty here, as the cached result is a React node @@ -155,10 +156,16 @@ function createClassProxy(InitialComponent, proxyKey, options) { return renderOptions.componentDidRender(result) } + function proxiedRender() { + renderOptions.componentWillRender(this) + return hotComponentRender.call(this) + } + const defineProxyMethods = (Proxy, Base = {}) => { defineClassMembers(Proxy, { ...fakeBasePrototype(Base), render: proxiedRender, + hotComponentRender, componentDidMount, componentWillReceiveProps, componentWillUnmount, diff --git a/src/reconciler/hotReplacementRender.js b/src/reconciler/hotReplacementRender.js index 71623cf9d..826279ac6 100644 --- a/src/reconciler/hotReplacementRender.js +++ b/src/reconciler/hotReplacementRender.js @@ -101,7 +101,11 @@ const render = component => { return [] } if (isReactClass(component)) { - return component.render() + // not calling real render method to prevent call recursion. + // stateless componets does not have hotComponentRender + return component.hotComponentRender + ? component.hotComponentRender() + : component.render() } if (isArray(component)) { return component.map(render) diff --git a/test/proxy/consistency.test.js b/test/proxy/consistency.test.js index 05cae00f2..90334cb48 100644 --- a/test/proxy/consistency.test.js +++ b/test/proxy/consistency.test.js @@ -278,6 +278,7 @@ describe('consistency', () => { 'methodA', 'methodB', 'render', + 'hotComponentRender', 'componentDidMount', 'componentWillReceiveProps', 'componentWillUnmount',