Skip to content

Commit 21a345a

Browse files
committed
added enableConsoleLogsInDoubleRender
1 parent 8723e77 commit 21a345a

13 files changed

+276
-17
lines changed

packages/react-reconciler/src/ReactFiberReconciler.new.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ import {
3535
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
3636
import invariant from 'shared/invariant';
3737
import isArray from 'shared/isArray';
38-
import {enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
38+
import {
39+
enableSchedulingProfiler,
40+
enableConsoleLogsInDoubleRender,
41+
} from 'shared/ReactFeatureFlags';
3942
import ReactSharedInternals from 'shared/ReactSharedInternals';
4043
import {getPublicInstance} from './ReactFiberHostConfig';
4144
import {
@@ -107,6 +110,7 @@ export {
107110

108111
import * as Scheduler from './Scheduler';
109112
import {setSuppressWarning} from 'shared/consoleWithStackDev';
113+
import {disableLogs, reenableLogs} from 'shared/ConsolePatchingDev';
110114

111115
type OpaqueRoot = FiberRoot;
112116

@@ -717,14 +721,23 @@ export function getIsStrictModeForDevtools() {
717721
}
718722

719723
export function setIsStrictModeForDevtools(newIsStrictMode: boolean) {
720-
// We're in a test because Scheduler.unstable_yieldValue only exists
721-
// in SchedulerMock. To reduce the noise in strict mode tests,
722-
// suppress warnings and disable scheduler yielding during the double render
723-
if (typeof Scheduler.unstable_yieldValue === 'function') {
724-
Scheduler.unstable_setDisableYieldValue(newIsStrictMode);
725-
setSuppressWarning(newIsStrictMode);
726-
}
727724
isStrictMode = newIsStrictMode;
725+
726+
if (enableConsoleLogsInDoubleRender) {
727+
// We're in a test because Scheduler.unstable_yieldValue only exists
728+
// in SchedulerMock. To reduce the noise in strict mode tests,
729+
// suppress warnings and disable scheduler yielding during the double render
730+
if (typeof Scheduler.unstable_yieldValue === 'function') {
731+
Scheduler.unstable_setDisableYieldValue(newIsStrictMode);
732+
setSuppressWarning(newIsStrictMode);
733+
}
734+
} else {
735+
if (newIsStrictMode) {
736+
disableLogs();
737+
} else {
738+
reenableLogs();
739+
}
740+
}
728741
}
729742

730743
export function injectIntoDevTools(devToolsConfig: DevToolsConfig): boolean {

packages/react-reconciler/src/ReactFiberReconciler.old.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ import {
3535
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
3636
import invariant from 'shared/invariant';
3737
import isArray from 'shared/isArray';
38-
import {enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
38+
import {
39+
enableSchedulingProfiler,
40+
enableConsoleLogsInDoubleRender,
41+
} from 'shared/ReactFeatureFlags';
3942
import ReactSharedInternals from 'shared/ReactSharedInternals';
4043
import {getPublicInstance} from './ReactFiberHostConfig';
4144
import {
@@ -107,6 +110,7 @@ export {
107110

108111
import * as Scheduler from './Scheduler';
109112
import {setSuppressWarning} from 'shared/consoleWithStackDev';
113+
import {disableLogs, reenableLogs} from 'shared/ConsolePatchingDev';
110114

111115
type OpaqueRoot = FiberRoot;
112116

@@ -717,14 +721,23 @@ export function getIsStrictModeForDevtools() {
717721
}
718722

719723
export function setIsStrictModeForDevtools(newIsStrictMode: boolean) {
720-
// We're in a test because Scheduler.unstable_yieldValue only exists
721-
// in SchedulerMock. To reduce the noise in strict mode tests,
722-
// suppress warnings and disable scheduler yielding during the double render
723-
if (typeof Scheduler.unstable_yieldValue === 'function') {
724-
Scheduler.unstable_setDisableYieldValue(newIsStrictMode);
725-
setSuppressWarning(newIsStrictMode);
726-
}
727724
isStrictMode = newIsStrictMode;
725+
726+
if (enableConsoleLogsInDoubleRender) {
727+
// We're in a test because Scheduler.unstable_yieldValue only exists
728+
// in SchedulerMock. To reduce the noise in strict mode tests,
729+
// suppress warnings and disable scheduler yielding during the double render
730+
if (typeof Scheduler.unstable_yieldValue === 'function') {
731+
Scheduler.unstable_setDisableYieldValue(newIsStrictMode);
732+
setSuppressWarning(newIsStrictMode);
733+
}
734+
} else {
735+
if (newIsStrictMode) {
736+
disableLogs();
737+
} else {
738+
reenableLogs();
739+
}
740+
}
728741
}
729742

730743
export function injectIntoDevTools(devToolsConfig: DevToolsConfig): boolean {

packages/react/src/__tests__/ReactStrictMode-test.js

Lines changed: 214 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
let React;
1313
let ReactDOM;
1414
let ReactDOMServer;
15+
let ReactFeatureFlags;
1516
let Scheduler;
1617
let PropTypes;
1718

@@ -893,7 +894,17 @@ describe('context legacy', () => {
893894
ReactDOM.render(<Root />, container);
894895
});
895896

896-
describe('logging', () => {
897+
describe('enable console logs logging', () => {
898+
beforeEach(() => {
899+
jest.resetModules();
900+
901+
ReactFeatureFlags = require('shared/ReactFeatureFlags');
902+
React = require('react');
903+
ReactDOM = require('react-dom');
904+
905+
ReactFeatureFlags.enableConsoleLogsInDoubleRender = true;
906+
});
907+
897908
it('does not disable logs for class double render', () => {
898909
spyOnDevAndProd(console, 'log');
899910

@@ -1084,4 +1095,206 @@ describe('context legacy', () => {
10841095
expect(console.log).toBeCalledWith('foo 1');
10851096
});
10861097
});
1098+
1099+
describe('disable console logs logging', () => {
1100+
beforeEach(() => {
1101+
jest.resetModules();
1102+
1103+
ReactFeatureFlags = require('shared/ReactFeatureFlags');
1104+
React = require('react');
1105+
ReactDOM = require('react-dom');
1106+
1107+
ReactFeatureFlags.enableConsoleLogsInDoubleRender = false;
1108+
});
1109+
1110+
it('disable logs for class double render', () => {
1111+
spyOnDevAndProd(console, 'log');
1112+
1113+
let count = 0;
1114+
class Foo extends React.Component {
1115+
render() {
1116+
count++;
1117+
console.log('foo ' + count);
1118+
return null;
1119+
}
1120+
}
1121+
1122+
const container = document.createElement('div');
1123+
ReactDOM.render(
1124+
<React.StrictMode>
1125+
<Foo />
1126+
</React.StrictMode>,
1127+
container,
1128+
);
1129+
1130+
expect(count).toBe(__DEV__ ? 2 : 1);
1131+
expect(console.log).toBeCalledTimes(1);
1132+
// Note: we should display the first log because otherwise
1133+
// there is a risk of suppressing warnings when they happen,
1134+
// and on the next render they'd get deduplicated and ignored.
1135+
expect(console.log).toBeCalledWith('foo 1');
1136+
});
1137+
1138+
it('disables logs for class double ctor', () => {
1139+
spyOnDevAndProd(console, 'log');
1140+
1141+
let count = 0;
1142+
class Foo extends React.Component {
1143+
constructor(props) {
1144+
super(props);
1145+
count++;
1146+
console.log('foo ' + count);
1147+
}
1148+
render() {
1149+
return null;
1150+
}
1151+
}
1152+
1153+
const container = document.createElement('div');
1154+
ReactDOM.render(
1155+
<React.StrictMode>
1156+
<Foo />
1157+
</React.StrictMode>,
1158+
container,
1159+
);
1160+
1161+
expect(count).toBe(__DEV__ ? 2 : 1);
1162+
expect(console.log).toBeCalledTimes(1);
1163+
// Note: we should display the first log because otherwise
1164+
// there is a risk of suppressing warnings when they happen,
1165+
// and on the next render they'd get deduplicated and ignored.
1166+
expect(console.log).toBeCalledWith('foo 1');
1167+
});
1168+
1169+
it('disable logs for class double getDerivedStateFromProps', () => {
1170+
spyOnDevAndProd(console, 'log');
1171+
1172+
let count = 0;
1173+
class Foo extends React.Component {
1174+
state = {};
1175+
static getDerivedStateFromProps() {
1176+
count++;
1177+
console.log('foo ' + count);
1178+
return {};
1179+
}
1180+
render() {
1181+
return null;
1182+
}
1183+
}
1184+
1185+
const container = document.createElement('div');
1186+
ReactDOM.render(
1187+
<React.StrictMode>
1188+
<Foo />
1189+
</React.StrictMode>,
1190+
container,
1191+
);
1192+
1193+
expect(count).toBe(__DEV__ ? 2 : 1);
1194+
expect(console.log).toBeCalledTimes(1);
1195+
// Note: we should display the first log because otherwise
1196+
// there is a risk of suppressing warnings when they happen,
1197+
// and on the next render they'd get deduplicated and ignored.
1198+
expect(console.log).toBeCalledWith('foo 1');
1199+
});
1200+
1201+
it('disable logs for class double shouldComponentUpdate', () => {
1202+
spyOnDevAndProd(console, 'log');
1203+
1204+
let count = 0;
1205+
class Foo extends React.Component {
1206+
state = {};
1207+
shouldComponentUpdate() {
1208+
count++;
1209+
console.log('foo ' + count);
1210+
return {};
1211+
}
1212+
render() {
1213+
return null;
1214+
}
1215+
}
1216+
1217+
const container = document.createElement('div');
1218+
ReactDOM.render(
1219+
<React.StrictMode>
1220+
<Foo />
1221+
</React.StrictMode>,
1222+
container,
1223+
);
1224+
// Trigger sCU:
1225+
ReactDOM.render(
1226+
<React.StrictMode>
1227+
<Foo />
1228+
</React.StrictMode>,
1229+
container,
1230+
);
1231+
1232+
expect(count).toBe(__DEV__ ? 2 : 1);
1233+
expect(console.log).toBeCalledTimes(1);
1234+
// Note: we should display the first log because otherwise
1235+
// there is a risk of suppressing warnings when they happen,
1236+
// and on the next render they'd get deduplicated and ignored.
1237+
expect(console.log).toBeCalledWith('foo 1');
1238+
});
1239+
1240+
it('disable logs for class state updaters', () => {
1241+
spyOnDevAndProd(console, 'log');
1242+
1243+
let inst;
1244+
let count = 0;
1245+
class Foo extends React.Component {
1246+
state = {};
1247+
render() {
1248+
inst = this;
1249+
return null;
1250+
}
1251+
}
1252+
1253+
const container = document.createElement('div');
1254+
ReactDOM.render(
1255+
<React.StrictMode>
1256+
<Foo />
1257+
</React.StrictMode>,
1258+
container,
1259+
);
1260+
inst.setState(() => {
1261+
count++;
1262+
console.log('foo ' + count);
1263+
return {};
1264+
});
1265+
1266+
expect(count).toBe(__DEV__ ? 2 : 1);
1267+
expect(console.log).toBeCalledTimes(1);
1268+
// Note: we should display the first log because otherwise
1269+
// there is a risk of suppressing warnings when they happen,
1270+
// and on the next render they'd get deduplicated and ignored.
1271+
expect(console.log).toBeCalledWith('foo 1');
1272+
});
1273+
1274+
it('disable logs for function double render', () => {
1275+
spyOnDevAndProd(console, 'log');
1276+
1277+
let count = 0;
1278+
function Foo() {
1279+
count++;
1280+
console.log('foo ' + count);
1281+
return null;
1282+
}
1283+
1284+
const container = document.createElement('div');
1285+
ReactDOM.render(
1286+
<React.StrictMode>
1287+
<Foo />
1288+
</React.StrictMode>,
1289+
container,
1290+
);
1291+
1292+
expect(count).toBe(__DEV__ ? 2 : 1);
1293+
expect(console.log).toBeCalledTimes(1);
1294+
// Note: we should display the first log because otherwise
1295+
// there is a risk of suppressing warnings when they happen,
1296+
// and on the next render they'd get deduplicated and ignored.
1297+
expect(console.log).toBeCalledWith('foo 1');
1298+
});
1299+
});
10871300
});

packages/shared/ReactFeatureFlags.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,5 @@ export const enableSyncDefaultUpdates = true;
175175
export const allowConcurrentByDefault = false;
176176

177177
export const enablePersistentOffscreenHostContainer = false;
178+
179+
export const enableConsoleLogsInDoubleRender = false;

packages/shared/forks/ReactFeatureFlags.native-fb.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ export const enableLazyContextPropagation = false;
6969
export const enableSyncDefaultUpdates = true;
7070
export const allowConcurrentByDefault = true;
7171

72+
export const enableConsoleLogsInDoubleRender = false;
73+
7274
// Flow magic to verify the exports of this file match the original version.
7375
// eslint-disable-next-line no-unused-vars
7476
type Check<_X, Y: _X, X: Y = _X> = null;

packages/shared/forks/ReactFeatureFlags.native-oss.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ export const enableSyncDefaultUpdates = true;
6161
export const allowConcurrentByDefault = false;
6262
export const enablePersistentOffscreenHostContainer = false;
6363

64+
export const enableConsoleLogsInDoubleRender = false;
65+
6466
// Flow magic to verify the exports of this file match the original version.
6567
// eslint-disable-next-line no-unused-vars
6668
type Check<_X, Y: _X, X: Y = _X> = null;

packages/shared/forks/ReactFeatureFlags.test-renderer.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ export const enableSyncDefaultUpdates = true;
6161
export const allowConcurrentByDefault = false;
6262
export const enablePersistentOffscreenHostContainer = false;
6363

64+
export const enableConsoleLogsInDoubleRender = true;
65+
6466
// Flow magic to verify the exports of this file match the original version.
6567
// eslint-disable-next-line no-unused-vars
6668
type Check<_X, Y: _X, X: Y = _X> = null;

packages/shared/forks/ReactFeatureFlags.test-renderer.native.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ export const enableSyncDefaultUpdates = true;
6161
export const allowConcurrentByDefault = true;
6262
export const enablePersistentOffscreenHostContainer = false;
6363

64+
export const enableConsoleLogsInDoubleRender = true;
65+
6466
// Flow magic to verify the exports of this file match the original version.
6567
// eslint-disable-next-line no-unused-vars
6668
type Check<_X, Y: _X, X: Y = _X> = null;

packages/shared/forks/ReactFeatureFlags.test-renderer.www.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ export const enableSyncDefaultUpdates = true;
6161
export const allowConcurrentByDefault = true;
6262
export const enablePersistentOffscreenHostContainer = false;
6363

64+
export const enableConsoleLogsInDoubleRender = true;
65+
6466
// Flow magic to verify the exports of this file match the original version.
6567
// eslint-disable-next-line no-unused-vars
6668
type Check<_X, Y: _X, X: Y = _X> = null;

packages/shared/forks/ReactFeatureFlags.testing.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ export const enableSyncDefaultUpdates = true;
6161
export const allowConcurrentByDefault = false;
6262
export const enablePersistentOffscreenHostContainer = false;
6363

64+
export const enableConsoleLogsInDoubleRender = true;
65+
6466
// Flow magic to verify the exports of this file match the original version.
6567
// eslint-disable-next-line no-unused-vars
6668
type Check<_X, Y: _X, X: Y = _X> = null;

0 commit comments

Comments
 (0)