Skip to content

Commit 1eba12e

Browse files
committed
Deduplicated many warnings (#11140)
* 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() * Code review changes made for #11140
1 parent 84a2891 commit 1eba12e

File tree

6 files changed

+45
-27
lines changed

6 files changed

+45
-27
lines changed

packages/react-dom/src/client/ReactDOMFiberSelect.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,9 @@ var ReactDOMSelect = {
163163
};
164164

165165
if (__DEV__) {
166-
if (
167-
props.value !== undefined &&
168-
props.defaultValue !== undefined &&
169-
!didWarnValueDefaultValue
170-
) {
166+
if (props.value !== undefined && props.defaultValue !== undefined) {
171167
warning(
172-
false,
168+
didWarnValueDefaultValue,
173169
'Select elements must be either controlled or uncontrolled ' +
174170
'(specify either the value prop, or the defaultValue prop, but not ' +
175171
'both). Decide between using a controlled or uncontrolled select ' +

packages/react-dom/src/server/ReactPartialRenderer.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ if (__DEV__) {
7272
var {ReactDebugCurrentFrame} = require('shared/ReactGlobalSharedState');
7373
var currentDebugStack = null;
7474
var currentDebugElementStack = null;
75+
var errorInfo = {};
7576
var setCurrentDebugStack = function(stack: Array<Frame>) {
7677
var frame: Frame = stack[stack.length - 1];
7778
currentDebugElementStack = ((frame: any): FrameDev).debugElementStack;
@@ -175,15 +176,20 @@ function warnNoop(
175176
) {
176177
if (__DEV__) {
177178
var constructor = publicInstance.constructor;
179+
const currentComponent =
180+
(constructor && getComponentName(constructor)) || 'ReactClass';
181+
const currentComponentError = `${callerName}_${currentComponent}`;
182+
178183
warning(
179-
false,
184+
!!errorInfo[currentComponentError],
180185
'%s(...): Can only update a mounting component. ' +
181186
'This usually means you called %s() outside componentWillMount() on the server. ' +
182187
'This is a no-op.\n\nPlease check the code for the %s component.',
183188
callerName,
184189
callerName,
185-
(constructor && getComponentName(constructor)) || 'ReactClass',
190+
currentComponent,
186191
);
192+
errorInfo[currentComponentError] = true;
187193
}
188194
}
189195

packages/react-reconciler/src/ReactFiberClassComponent.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ if (__DEV__) {
4141
var warning = require('fbjs/lib/warning');
4242

4343
var {startPhaseTimer, stopPhaseTimer} = require('./ReactDebugFiberPerf');
44+
var stateDeprecationWarning = {};
4445

4546
var warnOnInvalidCallback = function(callback: mixed, callerName: string) {
4647
warning(
@@ -393,13 +394,16 @@ module.exports = function(
393394

394395
if (instance.state !== oldState) {
395396
if (__DEV__) {
397+
const currentComponent =
398+
getComponentName(workInProgress) || 'Component';
396399
warning(
397-
false,
400+
!!stateDeprecationWarning[currentComponent],
398401
'%s.componentWillReceiveProps(): Assigning directly to ' +
399402
"this.state is deprecated (except inside a component's " +
400403
'constructor). Use setState instead.',
401-
getComponentName(workInProgress),
404+
currentComponent,
402405
);
406+
stateDeprecationWarning[currentComponent] = true;
403407
}
404408
updater.enqueueReplaceState(instance, instance.state, null);
405409
}

packages/react-reconciler/src/ReactFiberScheduler.js

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -101,41 +101,45 @@ if (__DEV__) {
101101
} = require('./ReactDebugFiberPerf');
102102

103103
var didWarnAboutStateTransition = false;
104+
var didWarnSetStateChildContext = false;
105+
var ownerHasNoopWarning = {};
104106

105107
var warnAboutUpdateOnUnmounted = function(
106108
instance: React$ComponentType<any>,
107109
) {
108-
const ctor = instance.constructor;
110+
const ctor: Object = instance.constructor;
111+
const currentComponent =
112+
(ctor && (ctor.displayName || ctor.name)) || 'ReactClass';
113+
109114
warning(
110-
false,
111-
'Can only update a mounted or mounting component. This usually means ' +
112-
'you called setState, replaceState, or forceUpdate on an unmounted ' +
113-
'component. This is a no-op.\n\nPlease check the code for the ' +
114-
'%s component.',
115-
(ctor && (ctor.displayName || ctor.name)) || 'ReactClass',
115+
!!ownerHasNoopWarning[currentComponent],
116+
'Can only update a mounted or mounting ' +
117+
'component. This usually means you called setState, replaceState, ' +
118+
'or forceUpdate on an unmounted component. This is a no-op.\n\nPlease ' +
119+
'check the code for the %s component.',
120+
currentComponent,
116121
);
122+
ownerHasNoopWarning[currentComponent] = true;
117123
};
118124

119125
var warnAboutInvalidUpdates = function(instance: React$ComponentType<any>) {
120126
switch (ReactDebugCurrentFiber.phase) {
121127
case 'getChildContext':
122128
warning(
123-
false,
129+
didWarnSetStateChildContext,
124130
'setState(...): Cannot call setState() inside getChildContext()',
125131
);
132+
didWarnSetStateChildContext = true;
126133
break;
127134
case 'render':
128-
if (didWarnAboutStateTransition) {
129-
return;
130-
}
131-
didWarnAboutStateTransition = true;
132135
warning(
133-
false,
136+
didWarnAboutStateTransition,
134137
'Cannot update during an existing state transition (such as within ' +
135138
"`render` or another component's constructor). Render methods should " +
136139
'be a pure function of props and state; constructor side-effects are ' +
137140
'an anti-pattern, but can be moved to `componentWillMount`.',
138141
);
142+
didWarnAboutStateTransition = true;
139143
break;
140144
}
141145
};

packages/react-reconciler/src/ReactFiberUpdateQueue.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const {NoWork} = require('./ReactFiberExpirationTime');
2020

2121
if (__DEV__) {
2222
var warning = require('fbjs/lib/warning');
23+
var didWarnUpdateInsideUpdate = false;
2324
}
2425

2526
type PartialState<State, Props> =
@@ -134,12 +135,13 @@ function insertUpdateIntoFiber<State>(
134135
if (__DEV__) {
135136
if (queue1.isProcessing || (queue2 !== null && queue2.isProcessing)) {
136137
warning(
137-
false,
138+
didWarnUpdateInsideUpdate,
138139
'An update (setState, replaceState, or forceUpdate) was scheduled ' +
139140
'from inside an update function. Update functions should be pure, ' +
140141
'with zero side-effects. Consider using componentDidUpdate or a ' +
141142
'callback.',
142143
);
144+
didWarnUpdateInsideUpdate = true;
143145
}
144146
}
145147

packages/react/src/ReactNoopUpdateQueue.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,27 @@
99

1010
if (__DEV__) {
1111
var warning = require('fbjs/lib/warning');
12+
var errorInfo = {};
1213
}
1314

1415
function warnNoop(publicInstance, callerName) {
1516
if (__DEV__) {
1617
var constructor = publicInstance.constructor;
18+
const currentComponent =
19+
(constructor && (constructor.displayName || constructor.name)) ||
20+
'ReactClass';
21+
const currentComponentError = `${callerName}_${currentComponent}`;
22+
1723
warning(
18-
false,
24+
!!errorInfo[currentComponentError],
1925
'%s(...): Can only update a mounted or mounting component. ' +
2026
'This usually means you called %s() on an unmounted component. ' +
2127
'This is a no-op.\n\nPlease check the code for the %s component.',
2228
callerName,
2329
callerName,
24-
(constructor && (constructor.displayName || constructor.name)) ||
25-
'ReactClass',
30+
currentComponent,
2631
);
32+
errorInfo[currentComponentError] = true;
2733
}
2834
}
2935

0 commit comments

Comments
 (0)