From 9a4de8df50621e3d6c2727b8c5da18e2cd82a3cf Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Wed, 22 Feb 2017 13:38:14 -0800 Subject: [PATCH] Track which lifecycle method we're in during DEV Use this to detect setState inside of render instead of relying on the owner. --- .../shared/fiber/ReactFiberBeginWork.js | 16 ++++++++++++- .../shared/fiber/ReactFiberScheduler.js | 5 +++- .../fiber/isomorphic/ReactDebugLifeCycle.js | 24 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/renderers/shared/fiber/isomorphic/ReactDebugLifeCycle.js diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index ffe68983d4d6b..7974c0161afc3 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -66,6 +66,7 @@ var invariant = require('invariant'); if (__DEV__) { var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber'); + var ReactDebugLifeCycle = require('ReactDebugLifeCycle'); var warning = require('warning'); var warnedAboutStatelessRefs = {}; @@ -231,7 +232,11 @@ module.exports = function( if (__DEV__) { ReactCurrentOwner.current = workInProgress; + ReactDebugLifeCycle.current = workInProgress; + ReactDebugLifeCycle.phase = 'render'; nextChildren = fn(nextProps, context); + ReactDebugLifeCycle.current = null; + ReactDebugLifeCycle.phase = null; } else { nextChildren = fn(nextProps, context); } @@ -280,7 +285,16 @@ module.exports = function( // Rerender ReactCurrentOwner.current = workInProgress; - const nextChildren = instance.render(); + let nextChildren; + if (__DEV__) { + ReactDebugLifeCycle.current = workInProgress; + ReactDebugLifeCycle.phase = 'render'; + nextChildren = instance.render(); + ReactDebugLifeCycle.current = null; + ReactDebugLifeCycle.phase = null; + } else { + nextChildren = instance.render(); + } reconcileChildren(current, workInProgress, nextChildren); // Memoize props and state using the values we just used to render. // TODO: Restructure so we never read values from the instance. diff --git a/src/renderers/shared/fiber/ReactFiberScheduler.js b/src/renderers/shared/fiber/ReactFiberScheduler.js index 08da7527e66ef..570ca4e0d719a 100644 --- a/src/renderers/shared/fiber/ReactFiberScheduler.js +++ b/src/renderers/shared/fiber/ReactFiberScheduler.js @@ -89,6 +89,7 @@ if (__DEV__) { var warning = require('warning'); var ReactFiberInstrumentation = require('ReactFiberInstrumentation'); var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber'); + var ReactDebugLifeCycle = require('ReactDebugLifeCycle'); var { isProcessingChildContext, onEndProcessingChildContext, @@ -112,7 +113,7 @@ if (__DEV__) { false, 'setState(...): Cannot call setState() inside getChildContext()', ); - } else if (ReactCurrentOwner.current != null) { + } else if (ReactDebugLifeCycle.phase === 'render') { warning( false, 'Cannot update during an existing state transition (such as within ' + @@ -879,6 +880,8 @@ module.exports = function(config : HostConfig