Skip to content

Commit

Permalink
Deduplicated many warnings (facebook#11140)
Browse files Browse the repository at this point in the history
  Deduplicated the following warnings:

1.  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

2.  %s.componentWillReceiveProps(): Assigning directly to
    this.state is deprecated (except inside a component's
    constructor). Use setState instead.'

3.  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.

4.  setState(...): Cannot call setState() inside getChildContext()
  • Loading branch information
imanushree committed Oct 13, 2017
1 parent 339d6cb commit b4f36c3
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 26 deletions.
20 changes: 17 additions & 3 deletions src/isomorphic/modern/class/ReactNoopUpdateQueue.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,35 @@

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 +
'(...): Can only update a mounted or mounting component. ' +
'This usually means you called ' +
callerName +
'() on an unmounted component. ' +
'This is a no-op.\n\nPlease check the code for the ' +
currentComponent +
' component.';

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;
}
}

Expand Down
8 changes: 2 additions & 6 deletions src/renderers/dom/fiber/wrappers/ReactDOMFiberSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,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 ' +
Expand Down
4 changes: 3 additions & 1 deletion src/renderers/shared/fiber/ReactFiberClassComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const isArray = Array.isArray;
if (__DEV__) {
var {startPhaseTimer, stopPhaseTimer} = require('ReactDebugFiberPerf');
var warning = require('fbjs/lib/warning');
var didWarnStateDeprecation = false;
var warnOnInvalidCallback = function(callback: mixed, callerName: string) {
warning(
callback === null || typeof callback === 'function',
Expand Down Expand Up @@ -369,12 +370,13 @@ module.exports = function(
if (instance.state !== oldState) {
if (__DEV__) {
warning(
false,
didWarnStateDeprecation,
'%s.componentWillReceiveProps(): Assigning directly to ' +
"this.state is deprecated (except inside a component's " +
'constructor). Use setState instead.',
getComponentName(workInProgress),
);
didWarnStateDeprecation = true;
}
updater.enqueueReplaceState(instance, instance.state, null);
}
Expand Down
37 changes: 24 additions & 13 deletions src/renderers/shared/fiber/ReactFiberScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,41 +111,52 @@ if (__DEV__) {
} = require('ReactDebugFiberPerf');

var didWarnAboutStateTransition = false;
var didWarnSetStateChildContext = false;
var ownerHasNoopWarning = {};

var warnAboutUpdateOnUnmounted = function(
instance: React$ComponentType<any>,
) {
const ctor = instance.constructor;
const ctor: Object = instance.constructor;
const currentComponent =
(ctor && (ctor.displayName || ctor.name)) || 'ReactClass';
const currentComponentErrorInfo =
'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 ' +
currentComponent +
' component.';

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[currentComponentErrorInfo],
'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[currentComponentErrorInfo] = true;
};

var warnAboutInvalidUpdates = function(instance: React$ComponentType<any>) {
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;
}
};
Expand Down
4 changes: 3 additions & 1 deletion src/renderers/shared/fiber/ReactFiberUpdateQueue.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const {ClassComponent, HostRoot} = require('ReactTypeOfWork');
const invariant = require('fbjs/lib/invariant');
if (__DEV__) {
var warning = require('fbjs/lib/warning');
var didWarnUpdateInsideUpdate = false;
}

type PartialState<State, Props> =
Expand Down Expand Up @@ -197,12 +198,13 @@ function insertUpdate(fiber: Fiber, update: Update): Update | null {
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;
}
}

Expand Down
19 changes: 17 additions & 2 deletions src/renderers/shared/server/ReactPartialRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ if (__DEV__) {
var {ReactDebugCurrentFrame} = require('ReactGlobalSharedState');
var currentDebugStack = null;
var currentDebugElementStack = null;
var errorInfo = {};

var setCurrentDebugStack = function(stack) {
currentDebugElementStack = stack[stack.length - 1].debugElementStack;
// We are about to enter a new composite stack, reset the array.
Expand Down Expand Up @@ -164,15 +166,28 @@ function warnNoop(
) {
if (__DEV__) {
var constructor = publicInstance.constructor;
const currentComponent =
(constructor && getComponentName(constructor)) || 'ReactClass';
const currentComponentError =
callerName +
'(...): Can only update a mounting component. ' +
'This usually means you called ' +
callerName +
'() outside componentWillMount() on the server. ' +
'This is a no-op.\n\nPlease check the code for the ' +
currentComponent +
' component.';

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;
}
}

Expand Down

0 comments on commit b4f36c3

Please sign in to comment.