diff --git a/packages/react-dom/src/client/ReactDOMFiberSelect.js b/packages/react-dom/src/client/ReactDOMFiberSelect.js index 60a4d1592bfc9..4be7c08d81ea9 100644 --- a/packages/react-dom/src/client/ReactDOMFiberSelect.js +++ b/packages/react-dom/src/client/ReactDOMFiberSelect.js @@ -163,13 +163,9 @@ var ReactDOMSelect = { }; if (__DEV__) { - if ( - props.value !== undefined && - props.defaultValue !== undefined && - !didWarnValueDefaultValue - ) { + if (props.value !== undefined && props.defaultValue !== undefined) { warning( - false, + didWarnValueDefaultValue, 'Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + diff --git a/packages/react-dom/src/server/ReactPartialRenderer.js b/packages/react-dom/src/server/ReactPartialRenderer.js index 62ea2e042824f..66c1cce2e0a07 100644 --- a/packages/react-dom/src/server/ReactPartialRenderer.js +++ b/packages/react-dom/src/server/ReactPartialRenderer.js @@ -72,6 +72,7 @@ if (__DEV__) { var {ReactDebugCurrentFrame} = require('shared/ReactGlobalSharedState'); var currentDebugStack = null; var currentDebugElementStack = null; + var errorInfo = {}; var setCurrentDebugStack = function(stack: Array) { var frame: Frame = stack[stack.length - 1]; currentDebugElementStack = ((frame: any): FrameDev).debugElementStack; @@ -175,15 +176,20 @@ function warnNoop( ) { if (__DEV__) { var constructor = publicInstance.constructor; + const currentComponent = + (constructor && getComponentName(constructor)) || 'ReactClass'; + const currentComponentError = `${callerName}_${currentComponent}`; + warning( - false, + !!errorInfo[currentComponentError], '%s(...): Can only update a mounting component. ' + 'This usually means you called %s() outside componentWillMount() on the server. ' + 'This is a no-op.\n\nPlease check the code for the %s component.', callerName, callerName, - (constructor && getComponentName(constructor)) || 'ReactClass', + currentComponent, ); + errorInfo[currentComponentError] = true; } } diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.js b/packages/react-reconciler/src/ReactFiberClassComponent.js index 396be01fb8ab0..fc9944dd0b01c 100644 --- a/packages/react-reconciler/src/ReactFiberClassComponent.js +++ b/packages/react-reconciler/src/ReactFiberClassComponent.js @@ -41,6 +41,7 @@ if (__DEV__) { var warning = require('fbjs/lib/warning'); var {startPhaseTimer, stopPhaseTimer} = require('./ReactDebugFiberPerf'); + var stateDeprecationWarning = {}; var warnOnInvalidCallback = function(callback: mixed, callerName: string) { warning( @@ -393,13 +394,16 @@ module.exports = function( if (instance.state !== oldState) { if (__DEV__) { + const currentComponent = + getComponentName(workInProgress) || 'Component'; warning( - false, + !!stateDeprecationWarning[currentComponent], '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', - getComponentName(workInProgress), + currentComponent, ); + stateDeprecationWarning[currentComponent] = true; } updater.enqueueReplaceState(instance, instance.state, null); } diff --git a/packages/react-reconciler/src/ReactFiberScheduler.js b/packages/react-reconciler/src/ReactFiberScheduler.js index 67a87c9a4a3f8..40d4b180bbec0 100644 --- a/packages/react-reconciler/src/ReactFiberScheduler.js +++ b/packages/react-reconciler/src/ReactFiberScheduler.js @@ -101,41 +101,45 @@ if (__DEV__) { } = require('./ReactDebugFiberPerf'); var didWarnAboutStateTransition = false; + var didWarnSetStateChildContext = false; + var ownerHasNoopWarning = {}; var warnAboutUpdateOnUnmounted = function( instance: React$ComponentType, ) { - const ctor = instance.constructor; + const ctor: Object = instance.constructor; + const currentComponent = + (ctor && (ctor.displayName || ctor.name)) || 'ReactClass'; + warning( - false, - 'Can only update a mounted or mounting component. This usually means ' + - 'you called setState, replaceState, or forceUpdate on an unmounted ' + - 'component. This is a no-op.\n\nPlease check the code for the ' + - '%s component.', - (ctor && (ctor.displayName || ctor.name)) || 'ReactClass', + !!ownerHasNoopWarning[currentComponent], + 'Can only update a mounted or mounting ' + + 'component. This usually means you called setState, replaceState, ' + + 'or forceUpdate on an unmounted component. This is a no-op.\n\nPlease ' + + 'check the code for the %s component.', + currentComponent, ); + ownerHasNoopWarning[currentComponent] = true; }; var warnAboutInvalidUpdates = function(instance: React$ComponentType) { switch (ReactDebugCurrentFiber.phase) { case 'getChildContext': warning( - false, + didWarnSetStateChildContext, 'setState(...): Cannot call setState() inside getChildContext()', ); + didWarnSetStateChildContext = true; break; case 'render': - if (didWarnAboutStateTransition) { - return; - } - didWarnAboutStateTransition = true; warning( - false, + didWarnAboutStateTransition, 'Cannot update during an existing state transition (such as within ' + "`render` or another component's constructor). Render methods should " + 'be a pure function of props and state; constructor side-effects are ' + 'an anti-pattern, but can be moved to `componentWillMount`.', ); + didWarnAboutStateTransition = true; break; } }; diff --git a/packages/react-reconciler/src/ReactFiberUpdateQueue.js b/packages/react-reconciler/src/ReactFiberUpdateQueue.js index 1fd6fa18cb8b2..e291b470c18f4 100644 --- a/packages/react-reconciler/src/ReactFiberUpdateQueue.js +++ b/packages/react-reconciler/src/ReactFiberUpdateQueue.js @@ -20,6 +20,7 @@ const {NoWork} = require('./ReactFiberExpirationTime'); if (__DEV__) { var warning = require('fbjs/lib/warning'); + var didWarnUpdateInsideUpdate = false; } type PartialState = @@ -134,12 +135,13 @@ function insertUpdateIntoFiber( if (__DEV__) { if (queue1.isProcessing || (queue2 !== null && queue2.isProcessing)) { warning( - false, + didWarnUpdateInsideUpdate, 'An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.', ); + didWarnUpdateInsideUpdate = true; } } diff --git a/packages/react/src/ReactNoopUpdateQueue.js b/packages/react/src/ReactNoopUpdateQueue.js index 5b0631dd08617..3ef10318ba032 100644 --- a/packages/react/src/ReactNoopUpdateQueue.js +++ b/packages/react/src/ReactNoopUpdateQueue.js @@ -9,21 +9,27 @@ if (__DEV__) { var warning = require('fbjs/lib/warning'); + var errorInfo = {}; } function warnNoop(publicInstance, callerName) { if (__DEV__) { var constructor = publicInstance.constructor; + const currentComponent = + (constructor && (constructor.displayName || constructor.name)) || + 'ReactClass'; + const currentComponentError = `${callerName}_${currentComponent}`; + warning( - false, + !!errorInfo[currentComponentError], '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op.\n\nPlease check the code for the %s component.', callerName, callerName, - (constructor && (constructor.displayName || constructor.name)) || - 'ReactClass', + currentComponent, ); + errorInfo[currentComponentError] = true; } }