Bump Prettier (#17811)
* Bump Prettier * Reformat * Use non-deprecated option
Dan Abramov committed
Jan 9, 2020 at 13:54 UTC
b979db4e7215957f03c4221622f0b115a868439a
158 files changed
+2341
-2392
.prettierrc.js
+1
-1
@@ -8,7 +8,7 @@ module.exports = {
8
jsxBracketSameLine: true,
9
trailingComma: 'es5',
10
printWidth: 80,
11
- parser: 'babylon',
11
+ parser: 'babel',
12
13
overrides: [
14
{
fixtures/attribute-behavior/src/App.js
+5
-9
@@ -461,9 +461,7 @@ function prepareState(initGlobals) {
461
hasSameBehaviorForAll,
462
rowPatternHash,
463
// "Good enough" id that we can store in localStorage
464
- rowIdHash: `${attribute.name} ${attribute.tagName} ${
465
- attribute.overrideStringValue
466
- }`,
464
+ rowIdHash: `${attribute.name} ${attribute.tagName} ${attribute.overrideStringValue}`,
465
};
466
const rowGroup = rowPatternHashes.get(rowPatternHash) || new Set();
467
rowGroup.add(row);
@@ -866,14 +864,12 @@ class App extends React.Component {
864
// Sort
865
switch (sortOrder) {
866
case ALPHABETICAL:
869
- return filteredAttributes.sort(
870
- (attr1, attr2) =>
871
- attr1.name.toLowerCase() < attr2.name.toLowerCase() ? -1 : 1
867
+ return filteredAttributes.sort((attr1, attr2) =>
868
+ attr1.name.toLowerCase() < attr2.name.toLowerCase() ? -1 : 1
869
);
870
case REV_ALPHABETICAL:
874
- return filteredAttributes.sort(
875
- (attr1, attr2) =>
876
- attr1.name.toLowerCase() < attr2.name.toLowerCase() ? 1 : -1
871
+ return filteredAttributes.sort((attr1, attr2) =>
872
+ attr1.name.toLowerCase() < attr2.name.toLowerCase() ? 1 : -1
873
);
874
case GROUPED_BY_ROW_PATTERN: {
875
return filteredAttributes.sort((attr1, attr2) => {
fixtures/dom/src/components/Iframe.js
+1
-1
@@ -55,4 +55,4 @@ class IframeSubtree extends React.Component {
55
}
56
}
57
58
-export default (ReactDOM.createPortal ? IframePortal : IframeSubtree);
58
+export default ReactDOM.createPortal ? IframePortal : IframeSubtree;
fixtures/dom/src/components/fixtures/home.js
+2
-1
@@ -33,7 +33,8 @@ export default function Home() {
33
<td>
34
<a href="https://www.mozilla.org/en-US/firefox/organizations/">
35
ESR<sup>†</sup>
36
- </a>, Latest
36
+ </a>
37
+ , Latest
38
</td>
39
</tr>
40
<tr>
fixtures/dom/src/components/fixtures/suspense/index.js
+5
-3
@@ -213,8 +213,8 @@ class TextInputFixtures extends React.Component {
213
214
<Fixture>
215
<SuspendyTree>
216
- <img src="https://upload.wikimedia.org/wikipedia/commons/e/ee/Atom_%282%29.png" />React
217
- is cool
216
+ <img src="https://upload.wikimedia.org/wikipedia/commons/e/ee/Atom_%282%29.png" />
217
+ React is cool
218
</SuspendyTree>
219
</Fixture>
220
</TestCase>
@@ -308,7 +308,9 @@ class TextInputFixtures extends React.Component {
308
<div style={{height: 200, overflow: 'scroll'}}>
309
{Array(20)
310
.fill()
311
- .map((_, i) => <h2 key={i}>{i + 1}</h2>)}
311
+ .map((_, i) => (
312
+ <h2 key={i}>{i + 1}</h2>
313
+ ))}
314
</div>
315
</SuspendyTree>
316
</Fixture>
fixtures/dom/src/toWarnDev.js
+1
-3
@@ -205,9 +205,7 @@ const createMatcherFor = consoleMethod =>
205
if (withoutStack !== warningsWithoutComponentStack.length) {
206
return {
207
message: () =>
208
- `Expected ${withoutStack} warnings without a component stack but received ${
209
- warningsWithoutComponentStack.length
210
- }:\n` +
208
+ `Expected ${withoutStack} warnings without a component stack but received ${warningsWithoutComponentStack.length}:\n` +
209
warningsWithoutComponentStack.map(warning =>
210
this.utils.printReceived(warning)
211
),
fixtures/eslint/index.js
+15
-18
@@ -8,22 +8,19 @@ function Comment({comment, commentSource}) {
8
const currentUserID = comment.viewer.id;
9
const environment = RelayEnvironment.forUser(currentUserID);
10
const commentID = nullthrows(comment.id);
11
- useEffect(
12
- () => {
13
- const subscription = SubscriptionCounter.subscribeOnce(
14
- `StoreSubscription_${commentID}`,
15
- () =>
16
- StoreSubscription.subscribe(
17
- environment,
18
- {
19
- comment_id: commentID,
20
- },
21
- currentUserID,
22
- commentSource
23
- )
24
- );
25
- return () => subscription.dispose();
26
- },
27
- [commentID, commentSource, currentUserID, environment]
28
- );
11
+ useEffect(() => {
12
+ const subscription = SubscriptionCounter.subscribeOnce(
13
+ `StoreSubscription_${commentID}`,
14
+ () =>
15
+ StoreSubscription.subscribe(
16
+ environment,
17
+ {
18
+ comment_id: commentID,
19
+ },
20
+ currentUserID,
21
+ commentSource
22
+ )
23
+ );
24
+ return () => subscription.dispose();
25
+ }, [commentID, commentSource, currentUserID, environment]);
26
}
fixtures/fiber-debugger/src/App.js
+1
-2
@@ -192,8 +192,7 @@ class App extends Component {
192
}
193
/>
194
<p>
195
- Step {currentStep}
196
- : {friendlyAction} (
195
+ Step {currentStep}: {friendlyAction} (
196
<a style={{color: 'gray'}} onClick={this.handleEdit} href="#">
197
Edit
198
</a>
fixtures/fiber-debugger/src/Fibers.js
+70
-77
@@ -330,83 +330,76 @@ export default function Fibers({fibers, show, graphSettings, ...rest}) {
330
]}
331
</div>
332
</Vertex>,
333
- fiber.child &&
334
- show.child && (
335
- <Edge
336
- source={fiber.id}
337
- target={fiber.child}
338
- kind="child"
339
- weight={1000}
340
- key={`${fiber.id}-${fiber.child}-child`}>
341
- child
342
- </Edge>
343
- ),
344
- fiber.sibling &&
345
- show.sibling && (
346
- <Edge
347
- source={fiber.id}
348
- target={fiber.sibling}
349
- kind="sibling"
350
- weight={2000}
351
- key={`${fiber.id}-${fiber.sibling}-sibling`}>
352
- sibling
353
- </Edge>
354
- ),
355
- fiber.return &&
356
- show.return && (
357
- <Edge
358
- source={fiber.id}
359
- target={fiber.return}
360
- kind="return"
361
- weight={1000}
362
- key={`${fiber.id}-${fiber.return}-return`}>
363
- return
364
- </Edge>
365
- ),
366
- fiber.nextEffect &&
367
- show.fx && (
368
- <Edge
369
- source={fiber.id}
370
- target={fiber.nextEffect}
371
- kind="fx"
372
- weight={100}
373
- key={`${fiber.id}-${fiber.nextEffect}-nextEffect`}>
374
- nextFx
375
- </Edge>
376
- ),
377
- fiber.firstEffect &&
378
- show.fx && (
379
- <Edge
380
- source={fiber.id}
381
- target={fiber.firstEffect}
382
- kind="fx"
383
- weight={100}
384
- key={`${fiber.id}-${fiber.firstEffect}-firstEffect`}>
385
- firstFx
386
- </Edge>
387
- ),
388
- fiber.lastEffect &&
389
- show.fx && (
390
- <Edge
391
- source={fiber.id}
392
- target={fiber.lastEffect}
393
- kind="fx"
394
- weight={100}
395
- key={`${fiber.id}-${fiber.lastEffect}-lastEffect`}>
396
- lastFx
397
- </Edge>
398
- ),
399
- fiber.alternate &&
400
- show.alt && (
401
- <Edge
402
- source={fiber.id}
403
- target={fiber.alternate}
404
- kind="alt"
405
- weight={10}
406
- key={`${fiber.id}-${fiber.alternate}-alt`}>
407
- alt
408
- </Edge>
409
- ),
333
+ fiber.child && show.child && (
334
+ <Edge
335
+ source={fiber.id}
336
+ target={fiber.child}
337
+ kind="child"
338
+ weight={1000}
339
+ key={`${fiber.id}-${fiber.child}-child`}>
340
+ child
341
+ </Edge>
342
+ ),
343
+ fiber.sibling && show.sibling && (
344
+ <Edge
345
+ source={fiber.id}
346
+ target={fiber.sibling}
347
+ kind="sibling"
348
+ weight={2000}
349
+ key={`${fiber.id}-${fiber.sibling}-sibling`}>
350
+ sibling
351
+ </Edge>
352
+ ),
353
+ fiber.return && show.return && (
354
+ <Edge
355
+ source={fiber.id}
356
+ target={fiber.return}
357
+ kind="return"
358
+ weight={1000}
359
+ key={`${fiber.id}-${fiber.return}-return`}>
360
+ return
361
+ </Edge>
362
+ ),
363
+ fiber.nextEffect && show.fx && (
364
+ <Edge
365
+ source={fiber.id}
366
+ target={fiber.nextEffect}
367
+ kind="fx"
368
+ weight={100}
369
+ key={`${fiber.id}-${fiber.nextEffect}-nextEffect`}>
370
+ nextFx
371
+ </Edge>
372
+ ),
373
+ fiber.firstEffect && show.fx && (
374
+ <Edge
375
+ source={fiber.id}
376
+ target={fiber.firstEffect}
377
+ kind="fx"
378
+ weight={100}
379
+ key={`${fiber.id}-${fiber.firstEffect}-firstEffect`}>
380
+ firstFx
381
+ </Edge>
382
+ ),
383
+ fiber.lastEffect && show.fx && (
384
+ <Edge
385
+ source={fiber.id}
386
+ target={fiber.lastEffect}
387
+ kind="fx"
388
+ weight={100}
389
+ key={`${fiber.id}-${fiber.lastEffect}-lastEffect`}>
390
+ lastFx
391
+ </Edge>
392
+ ),
393
+ fiber.alternate && show.alt && (
394
+ <Edge
395
+ source={fiber.id}
396
+ target={fiber.alternate}
397
+ kind="alt"
398
+ weight={10}
399
+ key={`${fiber.id}-${fiber.alternate}-alt`}>
400
+ alt
401
+ </Edge>
402
+ ),
403
])}
404
</Graph>
405
</div>
package.json
+1
-1
@@ -71,7 +71,7 @@
71
"ncp": "^2.0.0",
72
"object-assign": "^4.1.1",
73
"pacote": "^9.5.6",
74
- "prettier": "1.13.7",
74
+ "prettier": "1.19.1",
75
"prop-types": "^15.6.2",
76
"random-seed": "^0.3.0",
77
"react-lifecycles-compat": "^3.0.2",
packages/create-subscription/src/__tests__/createSubscription-test.internal.js
+8
-2
@@ -118,7 +118,10 @@ describe('createSubscription', () => {
118
const Subscription = createSubscription({
119
getCurrentValue: source => undefined,
120
subscribe: (source, callback) => {
121
- source.then(value => callback(value), value => callback(value));
121
+ source.then(
122
+ value => callback(value),
123
+ value => callback(value),
124
+ );
125
// (Can't unsubscribe from a Promise)
126
return () => {};
127
},
@@ -196,7 +199,10 @@ describe('createSubscription', () => {
199
const Subscription = createSubscription({
200
getCurrentValue: source => undefined,
201
subscribe: (source, callback) => {
199
- source.then(value => callback(value), value => callback(value));
202
+ source.then(
203
+ value => callback(value),
204
+ value => callback(value),
205
+ );
206
// (Can't unsubscribe from a Promise)
207
return () => {};
208
},
packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
+6
-18
@@ -613,21 +613,15 @@ export default {
613
context.report({
614
node: declaredDependencyNode,
615
message:
616
- `The ${
617
- declaredDependencyNode.raw
618
- } literal is not a valid dependency ` +
616
+ `The ${declaredDependencyNode.raw} literal is not a valid dependency ` +
617
`because it never changes. ` +
620
- `Did you mean to include ${
621
- declaredDependencyNode.value
622
- } in the array instead?`,
618
+ `Did you mean to include ${declaredDependencyNode.value} in the array instead?`,
619
});
620
} else {
621
context.report({
622
node: declaredDependencyNode,
623
message:
628
- `The ${
629
- declaredDependencyNode.raw
630
- } literal is not a valid dependency ` +
624
+ `The ${declaredDependencyNode.raw} literal is not a valid dependency ` +
625
'because it never changes. You can safely remove it.',
626
});
627
}
@@ -697,22 +691,16 @@ export default {
691
bareFunctions.forEach(({fn, suggestUseCallback}) => {
692
let message =
693
`The '${fn.name.name}' function makes the dependencies of ` +
700
- `${reactiveHookName} Hook (at line ${
701
- declaredDependenciesNode.loc.start.line
702
- }) ` +
694
+ `${reactiveHookName} Hook (at line ${declaredDependenciesNode.loc.start.line}) ` +
695
`change on every render.`;
696
if (suggestUseCallback) {
697
message +=
698
` To fix this, ` +
707
- `wrap the '${
708
- fn.name.name
709
- }' definition into its own useCallback() Hook.`;
699
+ `wrap the '${fn.name.name}' definition into its own useCallback() Hook.`;
700
} else {
701
message +=
702
` Move it inside the ${reactiveHookName} callback. ` +
713
- `Alternatively, wrap the '${
714
- fn.name.name
715
- }' definition into its own useCallback() Hook.`;
703
+ `Alternatively, wrap the '${fn.name.name}' definition into its own useCallback() Hook.`;
704
}
705
// TODO: What if the function needs to change on every render anyway?
706
// Should we suggest removing effect deps as an appropriate fix too?
packages/legacy-events/EventPluginUtils.js
+4
-4
@@ -40,15 +40,15 @@ if (__DEV__) {
40
const listenersLen = listenersIsArr
41
? dispatchListeners.length
42
: dispatchListeners
43
- ? 1
44
- : 0;
43
+ ? 1
44
+ : 0;
45
46
const instancesIsArr = Array.isArray(dispatchInstances);
47
const instancesLen = instancesIsArr
48
? dispatchInstances.length
49
: dispatchInstances
50
- ? 1
51
- : 0;
50
+ ? 1
51
+ : 0;
52
53
if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) {
54
console.error('EventPluginUtils: Invalid `event`.');
packages/legacy-events/ReactGenericBatching.js
+2
-1
@@ -119,7 +119,8 @@ export function flushDiscreteUpdatesIfNeeded(timeStamp: number) {
119
if (
120
!isInsideEventHandler &&
121
(!enableDeprecatedFlareAPI ||
122
- (timeStamp === 0 || lastFlushedEventTimeStamp !== timeStamp))
122
+ timeStamp === 0 ||
123
+ lastFlushedEventTimeStamp !== timeStamp)
124
) {
125
lastFlushedEventTimeStamp = timeStamp;
126
flushDiscreteUpdatesImpl();
packages/legacy-events/ResponderEventPlugin.js
+10
-10
@@ -350,10 +350,10 @@ function setResponderAndExtractTransfer(
350
const shouldSetEventType = isStartish(topLevelType)
351
? eventTypes.startShouldSetResponder
352
: isMoveish(topLevelType)
353
- ? eventTypes.moveShouldSetResponder
354
- : topLevelType === TOP_SELECTION_CHANGE
355
- ? eventTypes.selectionChangeShouldSetResponder
356
- : eventTypes.scrollShouldSetResponder;
353
+ ? eventTypes.moveShouldSetResponder
354
+ : topLevelType === TOP_SELECTION_CHANGE
355
+ ? eventTypes.selectionChangeShouldSetResponder
356
+ : eventTypes.scrollShouldSetResponder;
357
358
// TODO: stop one short of the current responder.
359
const bubbleShouldSetFrom = !responderInst
@@ -550,10 +550,10 @@ const ResponderEventPlugin = {
550
const incrementalTouch = isResponderTouchStart
551
? eventTypes.responderStart
552
: isResponderTouchMove
553
- ? eventTypes.responderMove
554
- : isResponderTouchEnd
555
- ? eventTypes.responderEnd
556
- : null;
553
+ ? eventTypes.responderMove
554
+ : isResponderTouchEnd
555
+ ? eventTypes.responderEnd
556
+ : null;
557
558
if (incrementalTouch) {
559
const gesture = ResponderSyntheticEvent.getPooled(
@@ -577,8 +577,8 @@ const ResponderEventPlugin = {
577
const finalTouch = isResponderTerminate
578
? eventTypes.responderTerminate
579
: isResponderRelease
580
- ? eventTypes.responderRelease
581
- : null;
580
+ ? eventTypes.responderRelease
581
+ : null;
582
if (finalTouch) {
583
const finalEvent = ResponderSyntheticEvent.getPooled(
584
finalTouch,
packages/legacy-events/__tests__/ResponderEventPlugin-test.internal.js
+6
-6
@@ -79,12 +79,12 @@ const _touchConfig = function(
79
topType === 'topTouchStart'
80
? allTouchObjects
81
: topType === 'topTouchMove'
82
- ? allTouchObjects
83
- : topType === 'topTouchEnd'
84
- ? antiSubsequence(allTouchObjects, changedIndices)
85
- : topType === 'topTouchCancel'
86
- ? antiSubsequence(allTouchObjects, changedIndices)
87
- : null;
82
+ ? allTouchObjects
83
+ : topType === 'topTouchEnd'
84
+ ? antiSubsequence(allTouchObjects, changedIndices)
85
+ : topType === 'topTouchCancel'
86
+ ? antiSubsequence(allTouchObjects, changedIndices)
87
+ : null;
88
89
return {
90
nativeEvent: touchEvent(
packages/react-art/src/__tests__/ReactART-test.js
+3
-1
@@ -214,7 +214,9 @@ describe('ReactART', () => {
214
const chars = this.props.chars.split('');
215
return (
216
<Surface>
217
- {chars.map(text => <Shape key={text} title={text} />)}
217
+ {chars.map(text => (
218
+ <Shape key={text} title={text} />
219
+ ))}
220
</Surface>
221
);
222
}
packages/react-cache/src/__tests__/ReactCache-test.internal.js
+66
-56
@@ -33,46 +33,53 @@ describe('ReactCache', () => {
33
ReactTestRenderer = require('react-test-renderer');
34
Scheduler = require('scheduler');
35
36
- TextResource = createResource(([text, ms = 0]) => {
37
- let listeners = null;
38
- let status = 'pending';
39
- let value = null;
40
- return {
41
- then(resolve, reject) {
42
- switch (status) {
43
- case 'pending': {
44
- if (listeners === null) {
45
- listeners = [{resolve, reject}];
46
- setTimeout(() => {
47
- if (textResourceShouldFail) {
48
- Scheduler.unstable_yieldValue(`Promise rejected [${text}]`);
49
- status = 'rejected';
50
- value = new Error('Failed to load: ' + text);
51
- listeners.forEach(listener => listener.reject(value));
52
- } else {
53
- Scheduler.unstable_yieldValue(`Promise resolved [${text}]`);
54
- status = 'resolved';
55
- value = text;
56
- listeners.forEach(listener => listener.resolve(value));
57
- }
58
- }, ms);
59
- } else {
60
- listeners.push({resolve, reject});
36
+ TextResource = createResource(
37
+ ([text, ms = 0]) => {
38
+ let listeners = null;
39
+ let status = 'pending';
40
+ let value = null;
41
+ return {
42
+ then(resolve, reject) {
43
+ switch (status) {
44
+ case 'pending': {
45
+ if (listeners === null) {
46
+ listeners = [{resolve, reject}];
47
+ setTimeout(() => {
48
+ if (textResourceShouldFail) {
49
+ Scheduler.unstable_yieldValue(
50
+ `Promise rejected [${text}]`,
51
+ );
52
+ status = 'rejected';
53
+ value = new Error('Failed to load: ' + text);
54
+ listeners.forEach(listener => listener.reject(value));
55
+ } else {
56
+ Scheduler.unstable_yieldValue(
57
+ `Promise resolved [${text}]`,
58
+ );
59
+ status = 'resolved';
60
+ value = text;
61
+ listeners.forEach(listener => listener.resolve(value));
62
+ }
63
+ }, ms);
64
+ } else {
65
+ listeners.push({resolve, reject});
66
+ }
67
+ break;
68
+ }
69
+ case 'resolved': {
70
+ resolve(value);
71
+ break;
72
+ }
73
+ case 'rejected': {
74
+ reject(value);
75
+ break;
76
}
62
- break;
63
- }
64
- case 'resolved': {
65
- resolve(value);
66
- break;
67
- }
68
- case 'rejected': {
69
- reject(value);
70
- break;
77
}
72
- }
73
- },
74
- };
75
- }, ([text, ms]) => text);
78
+ },
79
+ };
80
+ },
81
+ ([text, ms]) => text,
82
+ );
83
84
textResourceShouldFail = false;
85
});
@@ -293,26 +300,29 @@ describe('ReactCache', () => {
300
301
it('if a thenable resolves multiple times, does not update the first cached value', () => {
302
let resolveThenable;
296
- const BadTextResource = createResource(([text, ms = 0]) => {
297
- let listeners = null;
298
- let value = null;
299
- return {
300
- then(resolve, reject) {
301
- if (value !== null) {
302
- resolve(value);
303
- } else {
304
- if (listeners === null) {
305
- listeners = [resolve];
306
- resolveThenable = v => {
307
- listeners.forEach(listener => listener(v));
308
- };
303
+ const BadTextResource = createResource(
304
+ ([text, ms = 0]) => {
305
+ let listeners = null;
306
+ let value = null;
307
+ return {
308
+ then(resolve, reject) {
309
+ if (value !== null) {
310
+ resolve(value);
311
} else {
310
- listeners.push(resolve);
312
+ if (listeners === null) {
313
+ listeners = [resolve];
314
+ resolveThenable = v => {
315
+ listeners.forEach(listener => listener(v));
316
+ };
317
+ } else {
318
+ listeners.push(resolve);
319
+ }
320
}
312
- }
313
- },
314
- };
315
- }, ([text, ms]) => text);
321
+ },
322
+ };
323
+ },
324
+ ([text, ms]) => text,
325
+ );
326
327
function BadAsyncText(props) {
328
const text = props.text;
packages/react-debug-tools/src/ReactDebugHooks.js
+2
-2
@@ -116,8 +116,8 @@ function useState<S>(
116
hook !== null
117
? hook.memoizedState
118
: typeof initialState === 'function'
119
- ? initialState()
120
- : initialState;
119
+ ? initialState()
120
+ : initialState;
121
hookLog.push({primitive: 'State', stackError: new Error(), value: state});
122
return [state, (action: BasicStateAction<S>) => {}];
123
}
packages/react-devtools-core/src/backend.js
+2
-5
@@ -33,9 +33,7 @@ installHook(window);
33
34
const hook: DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
35
36
-let savedComponentFilters: Array<
37
- ComponentFilter,
38
-> = getDefaultComponentFilters();
36
+let savedComponentFilters: Array<ComponentFilter> = getDefaultComponentFilters();
37
38
function debug(methodName: string, ...args) {
39
if (__DEBUG__) {
@@ -56,8 +54,7 @@ export function connectToDevTools(options: ?ConnectOptions) {
54
websocket,
55
resolveRNStyle = null,
56
isAppActive = () => true,
59
- } =
60
- options || {};
57
+ } = options || {};
58
59
let retryTimeoutID: TimeoutID | null = null;
60
packages/react-devtools-shared/src/__tests__/inspectedElementContext-test.js
+8
-2
@@ -520,9 +520,15 @@ describe('InspectedElementContext', () => {
520
const exampleFunction = () => {};
521
const exampleDateISO = '2019-12-31T23:42:42.000Z';
522
const setShallow = new Set(['abc', 123]);
523
- const mapShallow = new Map([['name', 'Brian'], ['food', 'sushi']]);
523
+ const mapShallow = new Map([
524
+ ['name', 'Brian'],
525
+ ['food', 'sushi'],
526
+ ]);
527
const setOfSets = new Set([new Set(['a', 'b', 'c']), new Set([1, 2, 3])]);
525
- const mapOfMaps = new Map([['first', mapShallow], ['second', mapShallow]]);
528
+ const mapOfMaps = new Map([
529
+ ['first', mapShallow],
530
+ ['second', mapShallow],
531
+ ]);
532
const objectOfObjects = {
533
inner: {string: 'abc', number: 123, boolean: true},
534
};
packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js
+8
-2
@@ -151,9 +151,15 @@ describe('InspectedElementContext', () => {
151
const div = document.createElement('div');
152
const exampleFunction = () => {};
153
const setShallow = new Set(['abc', 123]);
154
- const mapShallow = new Map([['name', 'Brian'], ['food', 'sushi']]);
154
+ const mapShallow = new Map([
155
+ ['name', 'Brian'],
156
+ ['food', 'sushi'],
157
+ ]);
158
const setOfSets = new Set([new Set(['a', 'b', 'c']), new Set([1, 2, 3])]);
156
- const mapOfMaps = new Map([['first', mapShallow], ['second', mapShallow]]);
159
+ const mapOfMaps = new Map([
160
+ ['first', mapShallow],
161
+ ['second', mapShallow],
162
+ ]);
163
const objectOfObjects = {
164
inner: {string: 'abc', number: 123, boolean: true},
165
};
packages/react-devtools-shared/src/__tests__/legacy/storeLegacy-v15-test.js
+18
-6
@@ -63,7 +63,9 @@ describe('Store (legacy)', () => {
63
);
64
const Parent = ({count}) => (
65
<div>
66
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
66
+ {new Array(count).fill(true).map((_, index) => (
67
+ <Child key={index} />
68
+ ))}
69
</div>
70
);
71
const Child = () => <div>Hi!</div>;
@@ -83,7 +85,9 @@ describe('Store (legacy)', () => {
85
it('should support mount and update operations for multiple roots', () => {
86
const Parent = ({count}) => (
87
<div>
86
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
88
+ {new Array(count).fill(true).map((_, index) => (
89
+ <Child key={index} />
90
+ ))}
91
</div>
92
);
93
const Child = () => <div>Hi!</div>;
@@ -155,7 +159,9 @@ describe('Store (legacy)', () => {
159
);
160
const Parent = ({count}) => (
161
<div>
158
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
162
+ {new Array(count).fill(true).map((_, index) => (
163
+ <Child key={index} />
164
+ ))}
165
</div>
166
);
167
const Child = () => <div>Hi!</div>;
@@ -261,7 +267,9 @@ describe('Store (legacy)', () => {
267
it('should support mount and update operations', () => {
268
const Parent = ({count}) => (
269
<div>
264
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
270
+ {new Array(count).fill(true).map((_, index) => (
271
+ <Child key={index} />
272
+ ))}
273
</div>
274
);
275
const Child = () => <div>Hi!</div>;
@@ -297,7 +305,9 @@ describe('Store (legacy)', () => {
305
it('should support mount and update operations for multiple roots', () => {
306
const Parent = ({count}) => (
307
<div>
300
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
308
+ {new Array(count).fill(true).map((_, index) => (
309
+ <Child key={index} />
310
+ ))}
311
</div>
312
);
313
const Child = () => <div>Hi!</div>;
@@ -375,7 +385,9 @@ describe('Store (legacy)', () => {
385
);
386
const Parent = ({count}) => (
387
<div>
378
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
388
+ {new Array(count).fill(true).map((_, index) => (
389
+ <Child key={index} />
390
+ ))}
391
</div>
392
);
393
const Child = () => <div>Hi!</div>;
packages/react-devtools-shared/src/backend/views/Highlighter/index.js
+3
-3
@@ -103,9 +103,9 @@ export default function setupHighlighter(
103
104
let nodes: ?Array<HTMLElement> = null;
105
if (renderer !== null) {
106
- nodes = ((renderer.findNativeNodesForFiberID(id): any): ?Array<
107
- HTMLElement,
108
- >);
106
+ nodes = ((renderer.findNativeNodesForFiberID(
107
+ id,
108
+ ): any): ?Array<HTMLElement>);
109
}
110
111
if (nodes != null && nodes[0] != null) {
packages/react-devtools-shared/src/devtools/ContextMenu/ContextMenu.js
+34
-40
@@ -74,55 +74,49 @@ export default function ContextMenu({children, id}: Props) {
74
};
75
}, []);
76
77
- useEffect(
78
- () => {
79
- const showMenu = ({data, pageX, pageY}) => {
80
- setState({data, isVisible: true, pageX, pageY});
81
- };
82
- const hideMenu = () => setState(HIDDEN_STATE);
83
- return registerMenu(id, showMenu, hideMenu);
84
- },
85
- [id],
86
- );
87
-
88
- useLayoutEffect(
89
- () => {
90
- if (!state.isVisible) {
91
- return;
92
- }
77
+ useEffect(() => {
78
+ const showMenu = ({data, pageX, pageY}) => {
79
+ setState({data, isVisible: true, pageX, pageY});
80
+ };
81
+ const hideMenu = () => setState(HIDDEN_STATE);
82
+ return registerMenu(id, showMenu, hideMenu);
83
+ }, [id]);
84
94
- const menu = menuRef.current;
85
+ useLayoutEffect(() => {
86
+ if (!state.isVisible) {
87
+ return;
88
+ }
89
96
- const hideUnlessContains = event => {
97
- if (!menu.contains(event.target)) {
98
- setState(HIDDEN_STATE);
99
- }
100
- };
90
+ const menu = menuRef.current;
91
102
- const hide = event => {
92
+ const hideUnlessContains = event => {
93
+ if (!menu.contains(event.target)) {
94
setState(HIDDEN_STATE);
104
- };
95
+ }
96
+ };
97
106
- const ownerDocument = containerRef.current.ownerDocument;
107
- ownerDocument.addEventListener('mousedown', hideUnlessContains);
108
- ownerDocument.addEventListener('touchstart', hideUnlessContains);
109
- ownerDocument.addEventListener('keydown', hideUnlessContains);
98
+ const hide = event => {
99
+ setState(HIDDEN_STATE);
100
+ };
101
111
- const ownerWindow = ownerDocument.defaultView;
112
- ownerWindow.addEventListener('resize', hide);
102
+ const ownerDocument = containerRef.current.ownerDocument;
103
+ ownerDocument.addEventListener('mousedown', hideUnlessContains);
104
+ ownerDocument.addEventListener('touchstart', hideUnlessContains);
105
+ ownerDocument.addEventListener('keydown', hideUnlessContains);
106
114
- respositionToFit(menu, state.pageX, state.pageY);
107
+ const ownerWindow = ownerDocument.defaultView;
108
+ ownerWindow.addEventListener('resize', hide);
109
116
- return () => {
117
- ownerDocument.removeEventListener('mousedown', hideUnlessContains);
118
- ownerDocument.removeEventListener('touchstart', hideUnlessContains);
119
- ownerDocument.removeEventListener('keydown', hideUnlessContains);
110
+ respositionToFit(menu, state.pageX, state.pageY);
111
121
- ownerWindow.removeEventListener('resize', hide);
122
- };
123
- },
124
- [state],
125
- );
112
+ return () => {
113
+ ownerDocument.removeEventListener('mousedown', hideUnlessContains);
114
+ ownerDocument.removeEventListener('touchstart', hideUnlessContains);
115
+ ownerDocument.removeEventListener('keydown', hideUnlessContains);
116
+
117
+ ownerWindow.removeEventListener('resize', hide);
118
+ };
119
+ }, [state]);
120
121
if (!state.isVisible) {
122
return <div ref={bodyAccessorRef} />;
packages/react-devtools-shared/src/devtools/ContextMenu/useContextMenu.js
+20
-25
@@ -23,29 +23,24 @@ export default function useContextMenu({
23
|}) {
24
const {showMenu} = useContext(RegistryContext);
25
26
- useEffect(
27
- () => {
28
- if (ref.current !== null) {
29
- const handleContextMenu = event => {
30
- event.preventDefault();
31
- event.stopPropagation();
32
-
33
- const pageX =
34
- event.pageX || (event.touches && event.touches[0].pageX);
35
- const pageY =
36
- event.pageY || (event.touches && event.touches[0].pageY);
37
-
38
- showMenu({data, id, pageX, pageY});
39
- };
40
-
41
- const trigger = ref.current;
42
- trigger.addEventListener('contextmenu', handleContextMenu);
43
-
44
- return () => {
45
- trigger.removeEventListener('contextmenu', handleContextMenu);
46
- };
47
- }
48
- },
49
- [data, id, showMenu],
50
- );
26
+ useEffect(() => {
27
+ if (ref.current !== null) {
28
+ const handleContextMenu = event => {
29
+ event.preventDefault();
30
+ event.stopPropagation();
31
+
32
+ const pageX = event.pageX || (event.touches && event.touches[0].pageX);
33
+ const pageY = event.pageY || (event.touches && event.touches[0].pageY);
34
+
35
+ showMenu({data, id, pageX, pageY});
36
+ };
37
+
38
+ const trigger = ref.current;
39
+ trigger.addEventListener('contextmenu', handleContextMenu);
40
+
41
+ return () => {
42
+ trigger.removeEventListener('contextmenu', handleContextMenu);
43
+ };
44
+ }
45
+ }, [data, id, showMenu]);
46
}
packages/react-devtools-shared/src/devtools/store.js
+1
-3
@@ -364,9 +364,7 @@ export default class Store extends EventEmitter<{|
364
getElementAtIndex(index: number): Element | null {
365
if (index < 0 || index >= this.numElements) {
366
console.warn(
367
- `Invalid index ${index} specified; store contains ${
368
- this.numElements
369
- } items.`,
367
+ `Invalid index ${index} specified; store contains ${this.numElements} items.`,
368
);
369
370
return null;
packages/react-devtools-shared/src/devtools/utils.js
+1
-3
@@ -90,9 +90,7 @@ export function printStore(store: Store, includeWeight: boolean = false) {
90
// Make sure the pretty-printed test align with the Store's reported number of total rows.
91
if (rootWeight !== store.numElements) {
92
throw Error(
93
- `Inconsistent Store state. Individual root weights (${rootWeight}) do not match total weight (${
94
- store.numElements
95
- })`,
93
+ `Inconsistent Store state. Individual root weights (${rootWeight}) do not match total weight (${store.numElements})`,
94
);
95
}
96
packages/react-devtools-shared/src/devtools/views/Components/Element.js
+3
-6
@@ -193,12 +193,9 @@ type DisplayNameProps = {|
193
194
function DisplayName({displayName, id}: DisplayNameProps) {
195
const {searchIndex, searchResults, searchText} = useContext(TreeStateContext);
196
- const isSearchResult = useMemo(
197
- () => {
198
- return searchResults.includes(id);
199
- },
200
- [id, searchResults],
201
- );
196
+ const isSearchResult = useMemo(() => {
197
+ return searchResults.includes(id);
198
+ }, [id, searchResults]);
199
const isCurrentResult =
200
searchIndex !== null && id === searchResults[searchIndex];
201
packages/react-devtools-shared/src/devtools/views/Components/InspectHostNodesToggle.js
+6
-9
@@ -29,15 +29,12 @@ export default function InspectHostNodesToggle() {
29
[bridge],
30
);
31
32
- useEffect(
33
- () => {
34
- const onStopInspectingNative = () => setIsInspecting(false);
35
- bridge.addListener('stopInspectingNative', onStopInspectingNative);
36
- return () =>
37
- bridge.removeListener('stopInspectingNative', onStopInspectingNative);
38
- },
39
- [bridge],
40
- );
32
+ useEffect(() => {
33
+ const onStopInspectingNative = () => setIsInspecting(false);
34
+ bridge.addListener('stopInspectingNative', onStopInspectingNative);
35
+ return () =>
36
+ bridge.removeListener('stopInspectingNative', onStopInspectingNative);
37
+ }, [bridge]);
38
39
return (
40
<Toggle
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContext.js
+141
-148
@@ -162,169 +162,162 @@ function InspectedElementContextController({children}: Props) {
162
] = useState<InspectedElementFrontend | null>(null);
163
164
// This effect handler invalidates the suspense cache and schedules rendering updates with React.
165
- useEffect(
166
- () => {
167
- const onInspectedElement = (data: InspectedElementPayload) => {
168
- const {id} = data;
169
-
170
- let element;
171
-
172
- switch (data.type) {
173
- case 'no-change':
174
- case 'not-found':
175
- // No-op
176
- break;
177
- case 'hydrated-path':
178
- // Merge new data into previous object and invalidate cache
179
- element = store.getElementByID(id);
180
- if (element !== null) {
181
- if (currentlyInspectedElement != null) {
182
- const value = hydrateHelper(data.value, data.path);
183
- const inspectedElement = {...currentlyInspectedElement};
184
-
185
- fillInPath(inspectedElement, data.value, data.path, value);
186
-
187
- resource.write(element, inspectedElement);
188
-
189
- // Schedule update with React if the curently-selected element has been invalidated.
190
- if (id === selectedElementID) {
191
- setCurrentlyInspectedElement(inspectedElement);
192
- }
165
+ useEffect(() => {
166
+ const onInspectedElement = (data: InspectedElementPayload) => {
167
+ const {id} = data;
168
+
169
+ let element;
170
+
171
+ switch (data.type) {
172
+ case 'no-change':
173
+ case 'not-found':
174
+ // No-op
175
+ break;
176
+ case 'hydrated-path':
177
+ // Merge new data into previous object and invalidate cache
178
+ element = store.getElementByID(id);
179
+ if (element !== null) {
180
+ if (currentlyInspectedElement != null) {
181
+ const value = hydrateHelper(data.value, data.path);
182
+ const inspectedElement = {...currentlyInspectedElement};
183
+
184
+ fillInPath(inspectedElement, data.value, data.path, value);
185
+
186
+ resource.write(element, inspectedElement);
187
+
188
+ // Schedule update with React if the curently-selected element has been invalidated.
189
+ if (id === selectedElementID) {
190
+ setCurrentlyInspectedElement(inspectedElement);
191
}
192
}
195
- break;
196
- case 'full-data':
197
- const {
198
- canEditFunctionProps,
199
- canEditHooks,
200
- canToggleSuspense,
201
- canViewSource,
202
- hasLegacyContext,
203
- source,
204
- type,
205
- owners,
206
- context,
207
- hooks,
208
- props,
209
- state,
210
- } = ((data.value: any): InspectedElementBackend);
211
-
212
- const inspectedElement: InspectedElementFrontend = {
213
- canEditFunctionProps,
214
- canEditHooks,
215
- canToggleSuspense,
216
- canViewSource,
217
- hasLegacyContext,
218
- id,
219
- source,
220
- type,
221
- owners:
222
- owners === null
223
- ? null
224
- : owners.map(owner => {
225
- const [
226
- displayName,
227
- hocDisplayNames,
228
- ] = separateDisplayNameAndHOCs(
229
- owner.displayName,
230
- owner.type,
231
- );
232
- return {
233
- ...owner,
234
- displayName,
235
- hocDisplayNames,
236
- };
237
- }),
238
- context: hydrateHelper(context),
239
- hooks: hydrateHelper(hooks),
240
- props: hydrateHelper(props),
241
- state: hydrateHelper(state),
242
- };
243
-
244
- element = store.getElementByID(id);
245
- if (element !== null) {
246
- const request = inProgressRequests.get(element);
247
- if (request != null) {
248
- inProgressRequests.delete(element);
249
- batchedUpdates(() => {
250
- request.resolveFn(inspectedElement);
251
- setCurrentlyInspectedElement(inspectedElement);
252
- });
253
- } else {
254
- resource.write(element, inspectedElement);
255
-
256
- // Schedule update with React if the curently-selected element has been invalidated.
257
- if (id === selectedElementID) {
258
- setCurrentlyInspectedElement(inspectedElement);
259
- }
193
+ }
194
+ break;
195
+ case 'full-data':
196
+ const {
197
+ canEditFunctionProps,
198
+ canEditHooks,
199
+ canToggleSuspense,
200
+ canViewSource,
201
+ hasLegacyContext,
202
+ source,
203
+ type,
204
+ owners,
205
+ context,
206
+ hooks,
207
+ props,
208
+ state,
209
+ } = ((data.value: any): InspectedElementBackend);
210
+
211
+ const inspectedElement: InspectedElementFrontend = {
212
+ canEditFunctionProps,
213
+ canEditHooks,
214
+ canToggleSuspense,
215
+ canViewSource,
216
+ hasLegacyContext,
217
+ id,
218
+ source,
219
+ type,
220
+ owners:
221
+ owners === null
222
+ ? null
223
+ : owners.map(owner => {
224
+ const [
225
+ displayName,
226
+ hocDisplayNames,
227
+ ] = separateDisplayNameAndHOCs(
228
+ owner.displayName,
229
+ owner.type,
230
+ );
231
+ return {
232
+ ...owner,
233
+ displayName,
234
+ hocDisplayNames,
235
+ };
236
+ }),
237
+ context: hydrateHelper(context),
238
+ hooks: hydrateHelper(hooks),
239
+ props: hydrateHelper(props),
240
+ state: hydrateHelper(state),
241
+ };
242
+
243
+ element = store.getElementByID(id);
244
+ if (element !== null) {
245
+ const request = inProgressRequests.get(element);
246
+ if (request != null) {
247
+ inProgressRequests.delete(element);
248
+ batchedUpdates(() => {
249
+ request.resolveFn(inspectedElement);
250
+ setCurrentlyInspectedElement(inspectedElement);
251
+ });
252
+ } else {
253
+ resource.write(element, inspectedElement);
254
+
255
+ // Schedule update with React if the curently-selected element has been invalidated.
256
+ if (id === selectedElementID) {
257
+ setCurrentlyInspectedElement(inspectedElement);
258
}
259
}
262
- break;
263
- default:
264
- break;
265
- }
266
- };
260
+ }
261
+ break;
262
+ default:
263
+ break;
264
+ }
265
+ };
266
268
- bridge.addListener('inspectedElement', onInspectedElement);
269
- return () =>
270
- bridge.removeListener('inspectedElement', onInspectedElement);
271
- },
272
- [bridge, currentlyInspectedElement, selectedElementID, store],
273
- );
267
+ bridge.addListener('inspectedElement', onInspectedElement);
268
+ return () => bridge.removeListener('inspectedElement', onInspectedElement);
269
+ }, [bridge, currentlyInspectedElement, selectedElementID, store]);
270
271
// This effect handler polls for updates on the currently selected element.
276
- useEffect(
277
- () => {
278
- if (selectedElementID === null) {
279
- return () => {};
280
- }
272
+ useEffect(() => {
273
+ if (selectedElementID === null) {
274
+ return () => {};
275
+ }
276
282
- const rendererID = store.getRendererIDForElement(selectedElementID);
277
+ const rendererID = store.getRendererIDForElement(selectedElementID);
278
284
- let timeoutID: TimeoutID | null = null;
279
+ let timeoutID: TimeoutID | null = null;
280
286
- const sendRequest = () => {
287
- timeoutID = null;
281
+ const sendRequest = () => {
282
+ timeoutID = null;
283
289
- if (rendererID !== null) {
290
- bridge.send('inspectElement', {id: selectedElementID, rendererID});
291
- }
292
- };
293
-
294
- // Send the initial inspection request.
295
- // We'll poll for an update in the response handler below.
296
- sendRequest();
297
-
298
- const onInspectedElement = (data: InspectedElementPayload) => {
299
- // If this is the element we requested, wait a little bit and then ask for another update.
300
- if (data.id === selectedElementID) {
301
- switch (data.type) {
302
- case 'no-change':
303
- case 'full-data':
304
- case 'hydrated-path':
305
- if (timeoutID !== null) {
306
- clearTimeout(timeoutID);
307
- }
308
- timeoutID = setTimeout(sendRequest, 1000);
309
- break;
310
- default:
311
- break;
312
- }
284
+ if (rendererID !== null) {
285
+ bridge.send('inspectElement', {id: selectedElementID, rendererID});
286
+ }
287
+ };
288
+
289
+ // Send the initial inspection request.
290
+ // We'll poll for an update in the response handler below.
291
+ sendRequest();
292
+
293
+ const onInspectedElement = (data: InspectedElementPayload) => {
294
+ // If this is the element we requested, wait a little bit and then ask for another update.
295
+ if (data.id === selectedElementID) {
296
+ switch (data.type) {
297
+ case 'no-change':
298
+ case 'full-data':
299
+ case 'hydrated-path':
300
+ if (timeoutID !== null) {
301
+ clearTimeout(timeoutID);
302
+ }
303
+ timeoutID = setTimeout(sendRequest, 1000);
304
+ break;
305
+ default:
306
+ break;
307
}
314
- };
308
+ }
309
+ };
310
316
- bridge.addListener('inspectedElement', onInspectedElement);
311
+ bridge.addListener('inspectedElement', onInspectedElement);
312
318
- return () => {
319
- bridge.removeListener('inspectedElement', onInspectedElement);
313
+ return () => {
314
+ bridge.removeListener('inspectedElement', onInspectedElement);
315
321
- if (timeoutID !== null) {
322
- clearTimeout(timeoutID);
323
- }
324
- };
325
- },
326
- [bridge, selectedElementID, store],
327
- );
316
+ if (timeoutID !== null) {
317
+ clearTimeout(timeoutID);
318
+ }
319
+ };
320
+ }, [bridge, selectedElementID, store]);
321
322
const value = useMemo(
323
() => ({
packages/react-devtools-shared/src/devtools/views/Components/KeyValue.js
+11
-14
@@ -55,20 +55,17 @@ export default function KeyValue({
55
value[meta.inspectable] &&
56
value[meta.size] !== 0;
57
58
- useEffect(
59
- () => {
60
- if (
61
- isInspectable &&
62
- isOpen &&
63
- !prevIsOpenRef.current &&
64
- typeof inspectPath === 'function'
65
- ) {
66
- inspectPath(path);
67
- }
68
- prevIsOpenRef.current = isOpen;
69
- },
70
- [inspectPath, isInspectable, isOpen, path],
71
- );
58
+ useEffect(() => {
59
+ if (
60
+ isInspectable &&
61
+ isOpen &&
62
+ !prevIsOpenRef.current &&
63
+ typeof inspectPath === 'function'
64
+ ) {
65
+ inspectPath(path);
66
+ }
67
+ prevIsOpenRef.current = isOpen;
68
+ }, [inspectPath, isInspectable, isOpen, path]);
69
70
const toggleIsOpen = () => setIsOpen(prevIsOpen => !prevIsOpen);
71
packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/AutoSizeInput.js
+15
-18
@@ -65,27 +65,24 @@ export default function AutoSizeInput({
65
}, []);
66
67
// Resize input any time text changes
68
- useLayoutEffect(
69
- () => {
70
- if (hiddenDivRef.current === null) {
71
- return;
72
- }
68
+ useLayoutEffect(() => {
69
+ if (hiddenDivRef.current === null) {
70
+ return;
71
+ }
72
74
- const scrollWidth = hiddenDivRef.current.getBoundingClientRect().width;
75
- if (!scrollWidth) {
76
- return;
77
- }
73
+ const scrollWidth = hiddenDivRef.current.getBoundingClientRect().width;
74
+ if (!scrollWidth) {
75
+ return;
76
+ }
77
79
- // Adding an extra pixel avoids a slight horizontal scroll when changing text selection/cursor.
80
- // Not sure why this is, but the old DevTools did a similar thing.
81
- const targetWidth = Math.ceil(scrollWidth) + 1;
78
+ // Adding an extra pixel avoids a slight horizontal scroll when changing text selection/cursor.
79
+ // Not sure why this is, but the old DevTools did a similar thing.
80
+ const targetWidth = Math.ceil(scrollWidth) + 1;
81
83
- if (inputRef.current !== null) {
84
- inputRef.current.style.width = `${targetWidth}px`;
85
- }
86
- },
87
- [value],
88
- );
82
+ if (inputRef.current !== null) {
83
+ inputRef.current.style.width = `${targetWidth}px`;
84
+ }
85
+ }, [value]);
86
87
const isEmpty = value === '' || value === '""';
88
packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/context.js
+68
-74
@@ -102,94 +102,88 @@ function NativeStyleContextController({children}: Props) {
102
] = useState<StyleAndLayoutFrontend | null>(null);
103
104
// This effect handler invalidates the suspense cache and schedules rendering updates with React.
105
- useEffect(
106
- () => {
107
- const onStyleAndLayout = ({id, layout, style}: StyleAndLayoutBackend) => {
108
- let element = store.getElementByID(id);
109
- if (element !== null) {
110
- const styleAndLayout: StyleAndLayoutFrontend = {
111
- layout,
112
- style,
113
- };
114
- const request = inProgressRequests.get(element);
115
- if (request != null) {
116
- inProgressRequests.delete(element);
117
- batchedUpdates(() => {
118
- request.resolveFn(styleAndLayout);
119
- setCurrentStyleAndLayout(styleAndLayout);
120
- });
121
- } else {
122
- resource.write(element, styleAndLayout);
123
-
124
- // Schedule update with React if the currently-selected element has been invalidated.
125
- if (id === selectedElementID) {
126
- setCurrentStyleAndLayout(styleAndLayout);
127
- }
105
+ useEffect(() => {
106
+ const onStyleAndLayout = ({id, layout, style}: StyleAndLayoutBackend) => {
107
+ let element = store.getElementByID(id);
108
+ if (element !== null) {
109
+ const styleAndLayout: StyleAndLayoutFrontend = {
110
+ layout,
111
+ style,
112
+ };
113
+ const request = inProgressRequests.get(element);
114
+ if (request != null) {
115
+ inProgressRequests.delete(element);
116
+ batchedUpdates(() => {
117
+ request.resolveFn(styleAndLayout);
118
+ setCurrentStyleAndLayout(styleAndLayout);
119
+ });
120
+ } else {
121
+ resource.write(element, styleAndLayout);
122
+
123
+ // Schedule update with React if the currently-selected element has been invalidated.
124
+ if (id === selectedElementID) {
125
+ setCurrentStyleAndLayout(styleAndLayout);
126
}
127
}
130
- };
131
-
132
- bridge.addListener('NativeStyleEditor_styleAndLayout', onStyleAndLayout);
133
- return () =>
134
- bridge.removeListener(
135
- 'NativeStyleEditor_styleAndLayout',
136
- onStyleAndLayout,
137
- );
138
- },
139
- [bridge, currentStyleAndLayout, selectedElementID, store],
140
- );
141
-
142
- // This effect handler polls for updates on the currently selected element.
143
- useEffect(
144
- () => {
145
- if (selectedElementID === null) {
146
- return () => {};
128
}
129
+ };
130
149
- const rendererID = store.getRendererIDForElement(selectedElementID);
150
-
151
- let timeoutID: TimeoutID | null = null;
131
+ bridge.addListener('NativeStyleEditor_styleAndLayout', onStyleAndLayout);
132
+ return () =>
133
+ bridge.removeListener(
134
+ 'NativeStyleEditor_styleAndLayout',
135
+ onStyleAndLayout,
136
+ );
137
+ }, [bridge, currentStyleAndLayout, selectedElementID, store]);
138
153
- const sendRequest = () => {
154
- timeoutID = null;
139
+ // This effect handler polls for updates on the currently selected element.
140
+ useEffect(() => {
141
+ if (selectedElementID === null) {
142
+ return () => {};
143
+ }
144
156
- if (rendererID !== null) {
157
- bridge.send('NativeStyleEditor_measure', {
158
- id: selectedElementID,
159
- rendererID,
160
- });
161
- }
162
- };
145
+ const rendererID = store.getRendererIDForElement(selectedElementID);
146
164
- // Send the initial measurement request.
165
- // We'll poll for an update in the response handler below.
166
- sendRequest();
147
+ let timeoutID: TimeoutID | null = null;
148
168
- const onStyleAndLayout = ({id}: StyleAndLayoutBackend) => {
169
- // If this is the element we requested, wait a little bit and then ask for another update.
170
- if (id === selectedElementID) {
171
- if (timeoutID !== null) {
172
- clearTimeout(timeoutID);
173
- }
174
- timeoutID = setTimeout(sendRequest, 1000);
175
- }
176
- };
149
+ const sendRequest = () => {
150
+ timeoutID = null;
151
178
- bridge.addListener('NativeStyleEditor_styleAndLayout', onStyleAndLayout);
152
+ if (rendererID !== null) {
153
+ bridge.send('NativeStyleEditor_measure', {
154
+ id: selectedElementID,
155
+ rendererID,
156
+ });
157
+ }
158
+ };
159
180
- return () => {
181
- bridge.removeListener(
182
- 'NativeStyleEditor_styleAndLayout',
183
- onStyleAndLayout,
184
- );
160
+ // Send the initial measurement request.
161
+ // We'll poll for an update in the response handler below.
162
+ sendRequest();
163
164
+ const onStyleAndLayout = ({id}: StyleAndLayoutBackend) => {
165
+ // If this is the element we requested, wait a little bit and then ask for another update.
166
+ if (id === selectedElementID) {
167
if (timeoutID !== null) {
168
clearTimeout(timeoutID);
169
}
189
- };
190
- },
191
- [bridge, selectedElementID, store],
192
- );
170
+ timeoutID = setTimeout(sendRequest, 1000);
171
+ }
172
+ };
173
+
174
+ bridge.addListener('NativeStyleEditor_styleAndLayout', onStyleAndLayout);
175
+
176
+ return () => {
177
+ bridge.removeListener(
178
+ 'NativeStyleEditor_styleAndLayout',
179
+ onStyleAndLayout,
180
+ );
181
+
182
+ if (timeoutID !== null) {
183
+ clearTimeout(timeoutID);
184
+ }
185
+ };
186
+ }, [bridge, selectedElementID, store]);
187
188
const value = useMemo(
189
() => ({getStyleAndLayout}),
packages/react-devtools-shared/src/devtools/views/Components/OwnersListContext.js
+39
-48
@@ -73,60 +73,51 @@ function OwnersListContextController({children}: Props) {
73
[store],
74
);
75
76
- useEffect(
77
- () => {
78
- const onOwnersList = (ownersList: OwnersList) => {
79
- const id = ownersList.id;
80
-
81
- const element = store.getElementByID(id);
82
- if (element !== null) {
83
- const request = inProgressRequests.get(element);
84
- if (request != null) {
85
- inProgressRequests.delete(element);
86
-
87
- request.resolveFn(
88
- ownersList.owners === null
89
- ? null
90
- : ownersList.owners.map(owner => {
91
- const [
92
- displayNameWithoutHOCs,
93
- hocDisplayNames,
94
- ] = separateDisplayNameAndHOCs(
95
- owner.displayName,
96
- owner.type,
97
- );
98
-
99
- return {
100
- ...owner,
101
- displayName: displayNameWithoutHOCs,
102
- hocDisplayNames,
103
- };
104
- }),
105
- );
106
- }
76
+ useEffect(() => {
77
+ const onOwnersList = (ownersList: OwnersList) => {
78
+ const id = ownersList.id;
79
+
80
+ const element = store.getElementByID(id);
81
+ if (element !== null) {
82
+ const request = inProgressRequests.get(element);
83
+ if (request != null) {
84
+ inProgressRequests.delete(element);
85
+
86
+ request.resolveFn(
87
+ ownersList.owners === null
88
+ ? null
89
+ : ownersList.owners.map(owner => {
90
+ const [
91
+ displayNameWithoutHOCs,
92
+ hocDisplayNames,
93
+ ] = separateDisplayNameAndHOCs(owner.displayName, owner.type);
94
+
95
+ return {
96
+ ...owner,
97
+ displayName: displayNameWithoutHOCs,
98
+ hocDisplayNames,
99
+ };
100
+ }),
101
+ );
102
}
108
- };
103
+ }
104
+ };
105
110
- bridge.addListener('ownersList', onOwnersList);
111
- return () => bridge.removeListener('ownersList', onOwnersList);
112
- },
113
- [bridge, store],
114
- );
106
+ bridge.addListener('ownersList', onOwnersList);
107
+ return () => bridge.removeListener('ownersList', onOwnersList);
108
+ }, [bridge, store]);
109
110
// This effect requests an updated owners list any time the selected owner changes
117
- useEffect(
118
- () => {
119
- if (ownerID !== null) {
120
- const rendererID = store.getRendererIDForElement(ownerID);
121
- if (rendererID !== null) {
122
- bridge.send('getOwnersList', {id: ownerID, rendererID});
123
- }
111
+ useEffect(() => {
112
+ if (ownerID !== null) {
113
+ const rendererID = store.getRendererIDForElement(ownerID);
114
+ if (rendererID !== null) {
115
+ bridge.send('getOwnersList', {id: ownerID, rendererID});
116
}
117
+ }
118
126
- return () => {};
127
- },
128
- [bridge, ownerID, store],
129
- );
119
+ return () => {};
120
+ }, [bridge, ownerID, store]);
121
122
return (
123
<OwnersListContext.Provider value={read}>
packages/react-devtools-shared/src/devtools/views/Components/OwnersStack.js
+26
-32
@@ -128,30 +128,27 @@ export default function OwnerStack() {
128
129
const selectedOwner = owners[selectedIndex];
130
131
- useLayoutEffect(
132
- () => {
133
- // If we're already overflowing, then we don't need to re-measure items.
134
- // That's because once the owners stack is open, it can only get larger (by driling in).
135
- // A totally new stack can only be reached by exiting this mode and re-entering it.
136
- if (elementsBarRef.current === null || isOverflowing) {
137
- return () => {};
138
- }
139
-
140
- let totalWidth = 0;
141
- for (let i = 0; i < owners.length; i++) {
142
- const element = elementsBarRef.current.children[i];
143
- const computedStyle = getComputedStyle(element);
144
-
145
- totalWidth +=
146
- element.offsetWidth +
147
- parseInt(computedStyle.marginLeft, 10) +
148
- parseInt(computedStyle.marginRight, 10);
149
- }
150
-
151
- setElementsTotalWidth(totalWidth);
152
- },
153
- [elementsBarRef, isOverflowing, owners.length],
154
- );
131
+ useLayoutEffect(() => {
132
+ // If we're already overflowing, then we don't need to re-measure items.
133
+ // That's because once the owners stack is open, it can only get larger (by driling in).
134
+ // A totally new stack can only be reached by exiting this mode and re-entering it.
135
+ if (elementsBarRef.current === null || isOverflowing) {
136
+ return () => {};
137
+ }
138
+
139
+ let totalWidth = 0;
140
+ for (let i = 0; i < owners.length; i++) {
141
+ const element = elementsBarRef.current.children[i];
142
+ const computedStyle = getComputedStyle(element);
143
+
144
+ totalWidth +=
145
+ element.offsetWidth +
146
+ parseInt(computedStyle.marginLeft, 10) +
147
+ parseInt(computedStyle.marginRight, 10);
148
+ }
149
+
150
+ setElementsTotalWidth(totalWidth);
151
+ }, [elementsBarRef, isOverflowing, owners.length]);
152
153
return (
154
<div className={styles.OwnerStack}>
@@ -255,14 +252,11 @@ function ElementView({isSelected, owner, selectOwner}: ElementViewProps) {
252
const {displayName, hocDisplayNames, type} = owner;
253
const isInStore = store.containsElement(owner.id);
254
258
- const handleChange = useCallback(
259
- () => {
260
- if (isInStore) {
261
- selectOwner(owner);
262
- }
263
- },
264
- [isInStore, selectOwner, owner],
265
- );
255
+ const handleChange = useCallback(() => {
256
+ if (isInStore) {
257
+ selectOwner(owner);
258
+ }
259
+ }, [isInStore, selectOwner, owner]);
260
261
return (
262
<Toggle
packages/react-devtools-shared/src/devtools/views/Components/SearchInput.js
+20
-24
@@ -66,34 +66,30 @@ export default function SearchInput(props: Props) {
66
);
67
68
// Auto-focus search input
69
- useEffect(
70
- () => {
71
- if (inputRef.current === null) {
72
- return () => {};
73
- }
69
+ useEffect(() => {
70
+ if (inputRef.current === null) {
71
+ return () => {};
72
+ }
73
75
- const handleWindowKey = (event: KeyboardEvent) => {
76
- const {key, metaKey} = event;
77
- if (key === 'f' && metaKey) {
78
- if (inputRef.current !== null) {
79
- inputRef.current.focus();
80
- event.preventDefault();
81
- event.stopPropagation();
82
- }
74
+ const handleWindowKey = (event: KeyboardEvent) => {
75
+ const {key, metaKey} = event;
76
+ if (key === 'f' && metaKey) {
77
+ if (inputRef.current !== null) {
78
+ inputRef.current.focus();
79
+ event.preventDefault();
80
+ event.stopPropagation();
81
}
84
- };
82
+ }
83
+ };
84
86
- // It's important to listen to the ownerDocument to support the browser extension.
87
- // Here we use portals to render individual tabs (e.g. Profiler),
88
- // and the root document might belong to a different window.
89
- const ownerDocument = inputRef.current.ownerDocument;
90
- ownerDocument.addEventListener('keydown', handleWindowKey);
85
+ // It's important to listen to the ownerDocument to support the browser extension.
86
+ // Here we use portals to render individual tabs (e.g. Profiler),
87
+ // and the root document might belong to a different window.
88
+ const ownerDocument = inputRef.current.ownerDocument;
89
+ ownerDocument.addEventListener('keydown', handleWindowKey);
90
92
- return () =>
93
- ownerDocument.removeEventListener('keydown', handleWindowKey);
94
- },
95
- [inputRef],
96
- );
91
+ return () => ownerDocument.removeEventListener('keydown', handleWindowKey);
92
+ }, [inputRef]);
93
94
return (
95
<div className={styles.SearchInput}>
packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.js
+91
-105
@@ -72,51 +72,42 @@ export default function SelectedElement(_: Props) {
72
const inspectedElement =
73
inspectedElementID != null ? getInspectedElement(inspectedElementID) : null;
74
75
- const highlightElement = useCallback(
76
- () => {
77
- if (element !== null && inspectedElementID !== null) {
78
- const rendererID = store.getRendererIDForElement(inspectedElementID);
79
- if (rendererID !== null) {
80
- bridge.send('highlightNativeElement', {
81
- displayName: element.displayName,
82
- hideAfterTimeout: true,
83
- id: inspectedElementID,
84
- openNativeElementsPanel: true,
85
- rendererID,
86
- scrollIntoView: true,
87
- });
88
- }
89
- }
90
- },
91
- [bridge, element, inspectedElementID, store],
92
- );
93
-
94
- const logElement = useCallback(
95
- () => {
96
- if (inspectedElementID !== null) {
97
- const rendererID = store.getRendererIDForElement(inspectedElementID);
98
- if (rendererID !== null) {
99
- bridge.send('logElementToConsole', {
100
- id: inspectedElementID,
101
- rendererID,
102
- });
103
- }
75
+ const highlightElement = useCallback(() => {
76
+ if (element !== null && inspectedElementID !== null) {
77
+ const rendererID = store.getRendererIDForElement(inspectedElementID);
78
+ if (rendererID !== null) {
79
+ bridge.send('highlightNativeElement', {
80
+ displayName: element.displayName,
81
+ hideAfterTimeout: true,
82
+ id: inspectedElementID,
83
+ openNativeElementsPanel: true,
84
+ rendererID,
85
+ scrollIntoView: true,
86
+ });
87
}
105
- },
106
- [bridge, inspectedElementID, store],
107
- );
88
+ }
89
+ }, [bridge, element, inspectedElementID, store]);
90
109
- const viewSource = useCallback(
110
- () => {
111
- if (viewElementSourceFunction != null && inspectedElement !== null) {
112
- viewElementSourceFunction(
113
- inspectedElement.id,
114
- ((inspectedElement: any): InspectedElement),
115
- );
91
+ const logElement = useCallback(() => {
92
+ if (inspectedElementID !== null) {
93
+ const rendererID = store.getRendererIDForElement(inspectedElementID);
94
+ if (rendererID !== null) {
95
+ bridge.send('logElementToConsole', {
96
+ id: inspectedElementID,
97
+ rendererID,
98
+ });
99
}
117
- },
118
- [inspectedElement, viewElementSourceFunction],
119
- );
100
+ }
101
+ }, [bridge, inspectedElementID, store]);
102
+
103
+ const viewSource = useCallback(() => {
104
+ if (viewElementSourceFunction != null && inspectedElement !== null) {
105
+ viewElementSourceFunction(
106
+ inspectedElement.id,
107
+ ((inspectedElement: any): InspectedElement),
108
+ );
109
+ }
110
+ }, [inspectedElement, viewElementSourceFunction]);
111
112
// In some cases (e.g. FB internal usage) the standalone shell might not be able to view the source.
113
// To detect this case, we defer to an injected helper function (if present).
@@ -137,56 +128,53 @@ export default function SelectedElement(_: Props) {
128
inspectedElement != null && inspectedElement.canToggleSuspense;
129
130
// TODO (suspense toggle) Would be nice to eventually use a two setState pattern here as well.
140
- const toggleSuspended = useCallback(
141
- () => {
142
- let nearestSuspenseElement = null;
143
- let currentElement = element;
144
- while (currentElement !== null) {
145
- if (currentElement.type === ElementTypeSuspense) {
146
- nearestSuspenseElement = currentElement;
147
- break;
148
- } else if (currentElement.parentID > 0) {
149
- currentElement = store.getElementByID(currentElement.parentID);
150
- } else {
151
- currentElement = null;
152
- }
131
+ const toggleSuspended = useCallback(() => {
132
+ let nearestSuspenseElement = null;
133
+ let currentElement = element;
134
+ while (currentElement !== null) {
135
+ if (currentElement.type === ElementTypeSuspense) {
136
+ nearestSuspenseElement = currentElement;
137
+ break;
138
+ } else if (currentElement.parentID > 0) {
139
+ currentElement = store.getElementByID(currentElement.parentID);
140
+ } else {
141
+ currentElement = null;
142
}
143
+ }
144
155
- // If we didn't find a Suspense ancestor, we can't suspend.
156
- // Instead we can show a warning to the user.
157
- if (nearestSuspenseElement === null) {
158
- modalDialogDispatch({
159
- type: 'SHOW',
160
- content: <CannotSuspendWarningMessage />,
145
+ // If we didn't find a Suspense ancestor, we can't suspend.
146
+ // Instead we can show a warning to the user.
147
+ if (nearestSuspenseElement === null) {
148
+ modalDialogDispatch({
149
+ type: 'SHOW',
150
+ content: <CannotSuspendWarningMessage />,
151
+ });
152
+ } else {
153
+ const nearestSuspenseElementID = nearestSuspenseElement.id;
154
+
155
+ // If we're suspending from an arbitary (non-Suspense) component, select the nearest Suspense element in the Tree.
156
+ // This way when the fallback UI is shown and the current element is hidden, something meaningful is selected.
157
+ if (nearestSuspenseElement !== element) {
158
+ dispatch({
159
+ type: 'SELECT_ELEMENT_BY_ID',
160
+ payload: nearestSuspenseElementID,
161
});
162
- } else {
163
- const nearestSuspenseElementID = nearestSuspenseElement.id;
164
-
165
- // If we're suspending from an arbitary (non-Suspense) component, select the nearest Suspense element in the Tree.
166
- // This way when the fallback UI is shown and the current element is hidden, something meaningful is selected.
167
- if (nearestSuspenseElement !== element) {
168
- dispatch({
169
- type: 'SELECT_ELEMENT_BY_ID',
170
- payload: nearestSuspenseElementID,
171
- });
172
- }
173
-
174
- const rendererID = store.getRendererIDForElement(
175
- nearestSuspenseElementID,
176
- );
177
-
178
- // Toggle suspended
179
- if (rendererID !== null) {
180
- bridge.send('overrideSuspense', {
181
- id: nearestSuspenseElementID,
182
- rendererID,
183
- forceFallback: !isSuspended,
184
- });
185
- }
162
}
187
- },
188
- [bridge, dispatch, element, isSuspended, modalDialogDispatch, store],
189
- );
163
+
164
+ const rendererID = store.getRendererIDForElement(
165
+ nearestSuspenseElementID,
166
+ );
167
+
168
+ // Toggle suspended
169
+ if (rendererID !== null) {
170
+ bridge.send('overrideSuspense', {
171
+ id: nearestSuspenseElementID,
172
+ rendererID,
173
+ forceFallback: !isSuspended,
174
+ });
175
+ }
176
+ }
177
+ }, [bridge, dispatch, element, isSuspended, modalDialogDispatch, store]);
178
179
if (element === null) {
180
return (
@@ -417,23 +405,21 @@ function InspectedElementView({
405
406
<NativeStyleEditor />
407
420
- {ownerID === null &&
421
- owners !== null &&
422
- owners.length > 0 && (
423
- <div className={styles.Owners}>
424
- <div className={styles.OwnersHeader}>rendered by</div>
425
- {owners.map(owner => (
426
- <OwnerView
427
- key={owner.id}
428
- displayName={owner.displayName || 'Anonymous'}
429
- hocDisplayNames={owner.hocDisplayNames}
430
- id={owner.id}
431
- isInStore={store.containsElement(owner.id)}
432
- type={owner.type}
433
- />
434
- ))}
435
- </div>
436
- )}
408
+ {ownerID === null && owners !== null && owners.length > 0 && (
409
+ <div className={styles.Owners}>
410
+ <div className={styles.OwnersHeader}>rendered by</div>
411
+ {owners.map(owner => (
412
+ <OwnerView
413
+ key={owner.id}
414
+ displayName={owner.displayName || 'Anonymous'}
415
+ hocDisplayNames={owner.hocDisplayNames}
416
+ id={owner.id}
417
+ isInStore={store.containsElement(owner.id)}
418
+ type={owner.type}
419
+ />
420
+ ))}
421
+ </div>
422
+ )}
423
424
{source !== null && (
425
<Source fileName={source.fileName} lineNumber={source.lineNumber} />
packages/react-devtools-shared/src/devtools/views/Components/Tree.js
+110
-128
@@ -89,22 +89,16 @@ export default function Tree(props: Props) {
89
90
// Picking an element in the inspector should put focus into the tree.
91
// This ensures that keyboard navigation works right after picking a node.
92
- useEffect(
93
- () => {
94
- function handleStopInspectingNative(didSelectNode) {
95
- if (didSelectNode && focusTargetRef.current !== null) {
96
- focusTargetRef.current.focus();
97
- }
92
+ useEffect(() => {
93
+ function handleStopInspectingNative(didSelectNode) {
94
+ if (didSelectNode && focusTargetRef.current !== null) {
95
+ focusTargetRef.current.focus();
96
}
99
- bridge.addListener('stopInspectingNative', handleStopInspectingNative);
100
- return () =>
101
- bridge.removeListener(
102
- 'stopInspectingNative',
103
- handleStopInspectingNative,
104
- );
105
- },
106
- [bridge],
107
- );
97
+ }
98
+ bridge.addListener('stopInspectingNative', handleStopInspectingNative);
99
+ return () =>
100
+ bridge.removeListener('stopInspectingNative', handleStopInspectingNative);
101
+ }, [bridge]);
102
103
// This ref is passed down the context to elements.
104
// It lets them avoid autoscrolling to the same item many times
@@ -112,93 +106,87 @@ export default function Tree(props: Props) {
106
const lastScrolledIDRef = useRef<number | null>(null);
107
108
// Navigate the tree with up/down arrow keys.
115
- useEffect(
116
- () => {
117
- if (treeRef.current === null) {
118
- return () => {};
109
+ useEffect(() => {
110
+ if (treeRef.current === null) {
111
+ return () => {};
112
+ }
113
+
114
+ const handleKeyDown = (event: KeyboardEvent) => {
115
+ if ((event: any).target.tagName === 'INPUT' || event.defaultPrevented) {
116
+ return;
117
}
118
121
- const handleKeyDown = (event: KeyboardEvent) => {
122
- if ((event: any).target.tagName === 'INPUT' || event.defaultPrevented) {
123
- return;
124
- }
125
-
126
- // TODO We should ignore arrow keys if the focus is outside of DevTools.
127
- // Otherwise the inline (embedded) DevTools might change selection unexpectedly,
128
- // e.g. when a text input or a select has focus.
129
-
130
- let element;
131
- switch (event.key) {
132
- case 'ArrowDown':
133
- event.preventDefault();
134
- dispatch({type: 'SELECT_NEXT_ELEMENT_IN_TREE'});
135
- break;
136
- case 'ArrowLeft':
137
- event.preventDefault();
138
- element =
139
- selectedElementID !== null
140
- ? store.getElementByID(selectedElementID)
141
- : null;
142
- if (element !== null) {
143
- if (element.children.length > 0 && !element.isCollapsed) {
144
- store.toggleIsCollapsed(element.id, true);
145
- } else {
146
- dispatch({type: 'SELECT_PARENT_ELEMENT_IN_TREE'});
147
- }
119
+ // TODO We should ignore arrow keys if the focus is outside of DevTools.
120
+ // Otherwise the inline (embedded) DevTools might change selection unexpectedly,
121
+ // e.g. when a text input or a select has focus.
122
+
123
+ let element;
124
+ switch (event.key) {
125
+ case 'ArrowDown':
126
+ event.preventDefault();
127
+ dispatch({type: 'SELECT_NEXT_ELEMENT_IN_TREE'});
128
+ break;
129
+ case 'ArrowLeft':
130
+ event.preventDefault();
131
+ element =
132
+ selectedElementID !== null
133
+ ? store.getElementByID(selectedElementID)
134
+ : null;
135
+ if (element !== null) {
136
+ if (element.children.length > 0 && !element.isCollapsed) {
137
+ store.toggleIsCollapsed(element.id, true);
138
+ } else {
139
+ dispatch({type: 'SELECT_PARENT_ELEMENT_IN_TREE'});
140
}
149
- break;
150
- case 'ArrowRight':
151
- event.preventDefault();
152
- element =
153
- selectedElementID !== null
154
- ? store.getElementByID(selectedElementID)
155
- : null;
156
- if (element !== null) {
157
- if (element.children.length > 0 && element.isCollapsed) {
158
- store.toggleIsCollapsed(element.id, false);
159
- } else {
160
- dispatch({type: 'SELECT_CHILD_ELEMENT_IN_TREE'});
161
- }
141
+ }
142
+ break;
143
+ case 'ArrowRight':
144
+ event.preventDefault();
145
+ element =
146
+ selectedElementID !== null
147
+ ? store.getElementByID(selectedElementID)
148
+ : null;
149
+ if (element !== null) {
150
+ if (element.children.length > 0 && element.isCollapsed) {
151
+ store.toggleIsCollapsed(element.id, false);
152
+ } else {
153
+ dispatch({type: 'SELECT_CHILD_ELEMENT_IN_TREE'});
154
}
163
- break;
164
- case 'ArrowUp':
165
- event.preventDefault();
166
- dispatch({type: 'SELECT_PREVIOUS_ELEMENT_IN_TREE'});
167
- break;
168
- default:
169
- return;
170
- }
171
- setIsNavigatingWithKeyboard(true);
172
- };
173
-
174
- // It's important to listen to the ownerDocument to support the browser extension.
175
- // Here we use portals to render individual tabs (e.g. Profiler),
176
- // and the root document might belong to a different window.
177
- const ownerDocument = treeRef.current.ownerDocument;
178
- ownerDocument.addEventListener('keydown', handleKeyDown);
179
-
180
- return () => {
181
- ownerDocument.removeEventListener('keydown', handleKeyDown);
182
- };
183
- },
184
- [dispatch, selectedElementID, store],
185
- );
155
+ }
156
+ break;
157
+ case 'ArrowUp':
158
+ event.preventDefault();
159
+ dispatch({type: 'SELECT_PREVIOUS_ELEMENT_IN_TREE'});
160
+ break;
161
+ default:
162
+ return;
163
+ }
164
+ setIsNavigatingWithKeyboard(true);
165
+ };
166
+
167
+ // It's important to listen to the ownerDocument to support the browser extension.
168
+ // Here we use portals to render individual tabs (e.g. Profiler),
169
+ // and the root document might belong to a different window.
170
+ const ownerDocument = treeRef.current.ownerDocument;
171
+ ownerDocument.addEventListener('keydown', handleKeyDown);
172
+
173
+ return () => {
174
+ ownerDocument.removeEventListener('keydown', handleKeyDown);
175
+ };
176
+ }, [dispatch, selectedElementID, store]);
177
178
// Focus management.
179
const handleBlur = useCallback(() => setTreeFocused(false), []);
189
- const handleFocus = useCallback(
190
- () => {
191
- setTreeFocused(true);
192
-
193
- if (selectedElementIndex === null && numElements > 0) {
194
- dispatch({
195
- type: 'SELECT_ELEMENT_AT_INDEX',
196
- payload: 0,
197
- });
198
- }
199
- },
200
- [dispatch, numElements, selectedElementIndex],
201
- );
180
+ const handleFocus = useCallback(() => {
181
+ setTreeFocused(true);
182
+
183
+ if (selectedElementIndex === null && numElements > 0) {
184
+ dispatch({
185
+ type: 'SELECT_ELEMENT_AT_INDEX',
186
+ payload: 0,
187
+ });
188
+ }
189
+ }, [dispatch, numElements, selectedElementIndex]);
190
191
const handleKeyPress = useCallback(
192
event => {
@@ -237,34 +225,31 @@ export default function Tree(props: Props) {
225
// If we switch the selected element while using the keyboard,
226
// start highlighting it in the DOM instead of the last hovered node.
227
const searchRef = useRef({searchIndex, searchResults});
240
- useEffect(
241
- () => {
242
- let didSelectNewSearchResult = false;
243
- if (
244
- searchRef.current.searchIndex !== searchIndex ||
245
- searchRef.current.searchResults !== searchResults
246
- ) {
247
- searchRef.current.searchIndex = searchIndex;
248
- searchRef.current.searchResults = searchResults;
249
- didSelectNewSearchResult = true;
250
- }
251
- if (isNavigatingWithKeyboard || didSelectNewSearchResult) {
252
- if (selectedElementID !== null) {
253
- highlightNativeElement(selectedElementID);
254
- } else {
255
- bridge.send('clearNativeElementHighlight');
256
- }
228
+ useEffect(() => {
229
+ let didSelectNewSearchResult = false;
230
+ if (
231
+ searchRef.current.searchIndex !== searchIndex ||
232
+ searchRef.current.searchResults !== searchResults
233
+ ) {
234
+ searchRef.current.searchIndex = searchIndex;
235
+ searchRef.current.searchResults = searchResults;
236
+ didSelectNewSearchResult = true;
237
+ }
238
+ if (isNavigatingWithKeyboard || didSelectNewSearchResult) {
239
+ if (selectedElementID !== null) {
240
+ highlightNativeElement(selectedElementID);
241
+ } else {
242
+ bridge.send('clearNativeElementHighlight');
243
}
258
- },
259
- [
260
- bridge,
261
- isNavigatingWithKeyboard,
262
- highlightNativeElement,
263
- searchIndex,
264
- searchResults,
265
- selectedElementID,
266
- ],
267
- );
244
+ }
245
+ }, [
246
+ bridge,
247
+ isNavigatingWithKeyboard,
248
+ highlightNativeElement,
249
+ searchIndex,
250
+ searchResults,
251
+ selectedElementID,
252
+ ]);
253
254
// Highlight last hovered element.
255
const handleElementMouseEnter = useCallback(
@@ -284,12 +269,9 @@ export default function Tree(props: Props) {
269
setIsNavigatingWithKeyboard(false);
270
}, []);
271
287
- const handleMouseLeave = useCallback(
288
- () => {
289
- bridge.send('clearNativeElementHighlight');
290
- },
291
- [bridge],
292
- );
272
+ const handleMouseLeave = useCallback(() => {
273
+ bridge.send('clearNativeElementHighlight');
274
+ }, [bridge]);
275
276
// Let react-window know to re-render any time the underlying tree data changes.
277
// This includes the owner context, since it controls a filtered view of the tree.
packages/react-devtools-shared/src/devtools/views/Components/TreeContext.js
+40
-49
@@ -718,65 +718,56 @@ function TreeContextController({
718
);
719
720
// Listen for host element selections.
721
- useEffect(
722
- () => {
723
- const handleSelectFiber = (id: number) =>
724
- dispatchWrapper({type: 'SELECT_ELEMENT_BY_ID', payload: id});
725
- bridge.addListener('selectFiber', handleSelectFiber);
726
- return () => bridge.removeListener('selectFiber', handleSelectFiber);
727
- },
728
- [bridge, dispatchWrapper],
729
- );
721
+ useEffect(() => {
722
+ const handleSelectFiber = (id: number) =>
723
+ dispatchWrapper({type: 'SELECT_ELEMENT_BY_ID', payload: id});
724
+ bridge.addListener('selectFiber', handleSelectFiber);
725
+ return () => bridge.removeListener('selectFiber', handleSelectFiber);
726
+ }, [bridge, dispatchWrapper]);
727
728
// If a newly-selected search result or inspection selection is inside of a collapsed subtree, auto expand it.
729
// This needs to be a layout effect to avoid temporarily flashing an incorrect selection.
730
const prevSelectedElementID = useRef<number | null>(null);
734
- useLayoutEffect(
735
- () => {
736
- if (state.selectedElementID !== prevSelectedElementID.current) {
737
- prevSelectedElementID.current = state.selectedElementID;
738
-
739
- if (state.selectedElementID !== null) {
740
- let element = store.getElementByID(state.selectedElementID);
741
- if (element !== null && element.parentID > 0) {
742
- store.toggleIsCollapsed(element.parentID, false);
743
- }
731
+ useLayoutEffect(() => {
732
+ if (state.selectedElementID !== prevSelectedElementID.current) {
733
+ prevSelectedElementID.current = state.selectedElementID;
734
+
735
+ if (state.selectedElementID !== null) {
736
+ let element = store.getElementByID(state.selectedElementID);
737
+ if (element !== null && element.parentID > 0) {
738
+ store.toggleIsCollapsed(element.parentID, false);
739
}
740
}
746
- },
747
- [state.selectedElementID, store],
748
- );
741
+ }
742
+ }, [state.selectedElementID, store]);
743
744
// Mutations to the underlying tree may impact this context (e.g. search results, selection state).
751
- useEffect(
752
- () => {
753
- const handleStoreMutated = ([addedElementIDs, removedElementIDs]: [
754
- Array<number>,
755
- Map<number, number>,
756
- ]) => {
757
- dispatchWrapper({
758
- type: 'HANDLE_STORE_MUTATION',
759
- payload: [addedElementIDs, removedElementIDs],
760
- });
761
- };
762
-
763
- // Since this is a passive effect, the tree may have been mutated before our initial subscription.
764
- if (store.revision !== initialRevision) {
765
- // At the moment, we can treat this as a mutation.
766
- // We don't know which Elements were newly added/removed, but that should be okay in this case.
767
- // It would only impact the search state, which is unlikely to exist yet at this point.
768
- dispatchWrapper({
769
- type: 'HANDLE_STORE_MUTATION',
770
- payload: [[], new Map()],
771
- });
772
- }
745
+ useEffect(() => {
746
+ const handleStoreMutated = ([addedElementIDs, removedElementIDs]: [
747
+ Array<number>,
748
+ Map<number, number>,
749
+ ]) => {
750
+ dispatchWrapper({
751
+ type: 'HANDLE_STORE_MUTATION',
752
+ payload: [addedElementIDs, removedElementIDs],
753
+ });
754
+ };
755
+
756
+ // Since this is a passive effect, the tree may have been mutated before our initial subscription.
757
+ if (store.revision !== initialRevision) {
758
+ // At the moment, we can treat this as a mutation.
759
+ // We don't know which Elements were newly added/removed, but that should be okay in this case.
760
+ // It would only impact the search state, which is unlikely to exist yet at this point.
761
+ dispatchWrapper({
762
+ type: 'HANDLE_STORE_MUTATION',
763
+ payload: [[], new Map()],
764
+ });
765
+ }
766
774
- store.addListener('mutated', handleStoreMutated);
767
+ store.addListener('mutated', handleStoreMutated);
768
776
- return () => store.removeListener('mutated', handleStoreMutated);
777
- },
778
- [dispatchWrapper, initialRevision, store],
779
- );
769
+ return () => store.removeListener('mutated', handleStoreMutated);
770
+ }, [dispatchWrapper, initialRevision, store]);
771
772
return (
773
<TreeStateContext.Provider value={state}>
packages/react-devtools-shared/src/devtools/views/DevTools.js
+9
-12
@@ -126,18 +126,15 @@ export default function DevTools({
126
[enabledInspectedElementContextMenu, viewAttributeSourceFunction],
127
);
128
129
- useEffect(
130
- () => {
131
- return () => {
132
- try {
133
- bridge.shutdown();
134
- } catch (error) {
135
- // Attempting to use a disconnected port.
136
- }
137
- };
138
- },
139
- [bridge],
140
- );
129
+ useEffect(() => {
130
+ return () => {
131
+ try {
132
+ bridge.shutdown();
133
+ } catch (error) {
134
+ // Attempting to use a disconnected port.
135
+ }
136
+ };
137
+ }, [bridge]);
138
139
return (
140
<BridgeContext.Provider value={bridge}>
packages/react-devtools-shared/src/devtools/views/ModalDialog.js
+5
-8
@@ -111,14 +111,11 @@ function ModalDialogImpl(_: {||}) {
111
const {canBeDismissed, content, dispatch, title} = useContext(
112
ModalDialogContext,
113
);
114
- const dismissModal = useCallback(
115
- () => {
116
- if (canBeDismissed) {
117
- dispatch({type: 'HIDE'});
118
- }
119
- },
120
- [canBeDismissed, dispatch],
121
- );
114
+ const dismissModal = useCallback(() => {
115
+ if (canBeDismissed) {
116
+ dispatch({type: 'HIDE'});
117
+ }
118
+ }, [canBeDismissed, dispatch]);
119
const dialogRef = useRef<HTMLDivElement | null>(null);
120
121
// It's important to trap click events within the dialog,
packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js
+20
-26
@@ -94,32 +94,26 @@ function CommitFlamegraph({chartData, commitTree, height, width}: Props) {
94
const {lineHeight} = useContext(SettingsContext);
95
const {selectFiber, selectedFiberID} = useContext(ProfilerContext);
96
97
- const selectedChartNodeIndex = useMemo<number>(
98
- () => {
99
- if (selectedFiberID === null) {
100
- return 0;
101
- }
102
- // The selected node might not be in the tree for this commit,
103
- // so it's important that we have a fallback plan.
104
- const depth = chartData.idToDepthMap.get(selectedFiberID);
105
- return depth !== undefined ? depth - 1 : 0;
106
- },
107
- [chartData, selectedFiberID],
108
- );
109
-
110
- const selectedChartNode = useMemo(
111
- () => {
112
- if (selectedFiberID !== null) {
113
- return (
114
- chartData.rows[selectedChartNodeIndex].find(
115
- chartNode => chartNode.id === selectedFiberID,
116
- ) || null
117
- );
118
- }
119
- return null;
120
- },
121
- [chartData, selectedFiberID, selectedChartNodeIndex],
122
- );
97
+ const selectedChartNodeIndex = useMemo<number>(() => {
98
+ if (selectedFiberID === null) {
99
+ return 0;
100
+ }
101
+ // The selected node might not be in the tree for this commit,
102
+ // so it's important that we have a fallback plan.
103
+ const depth = chartData.idToDepthMap.get(selectedFiberID);
104
+ return depth !== undefined ? depth - 1 : 0;
105
+ }, [chartData, selectedFiberID]);
106
+
107
+ const selectedChartNode = useMemo(() => {
108
+ if (selectedFiberID !== null) {
109
+ return (
110
+ chartData.rows[selectedChartNodeIndex].find(
111
+ chartNode => chartNode.id === selectedFiberID,
112
+ ) || null
113
+ );
114
+ }
115
+ return null;
116
+ }, [chartData, selectedFiberID, selectedChartNodeIndex]);
117
118
const itemData = useMemo<ItemData>(
119
() => ({
packages/react-devtools-shared/src/devtools/views/Profiler/CommitTreeBuilder.js
+3
-3
@@ -51,9 +51,9 @@ export function getCommitTree({
51
rootToCommitTreeMap.set(rootID, []);
52
}
53
54
- const commitTrees = ((rootToCommitTreeMap.get(rootID): any): Array<
55
- CommitTree,
56
- >);
54
+ const commitTrees = ((rootToCommitTreeMap.get(
55
+ rootID,
56
+ ): any): Array<CommitTree>);
57
58
if (commitIndex < commitTrees.length) {
59
return commitTrees[commitIndex];
packages/react-devtools-shared/src/devtools/views/Profiler/InteractionListItem.js
+3
-6
@@ -41,12 +41,9 @@ function InteractionListItem({data: itemData, index, style}: Props) {
41
throw Error(`Could not find interaction #${index}`);
42
}
43
44
- const handleClick = useCallback(
45
- () => {
46
- selectInteraction(interaction.id);
47
- },
48
- [interaction, selectInteraction],
49
- );
44
+ const handleClick = useCallback(() => {
45
+ selectInteraction(interaction.id);
46
+ }, [interaction, selectInteraction]);
47
48
const commits = interactionCommits.get(interaction.id) || [];
49
packages/react-devtools-shared/src/devtools/views/Profiler/Interactions.js
+28
-31
@@ -87,45 +87,42 @@ function Interactions({height, width}: {|height: number, width: number|}) {
87
[interactions, selectedInteractionID, selectInteraction],
88
);
89
90
- const itemData = useMemo<ItemData>(
91
- () => {
92
- const interactionCommitSize = parseInt(
93
- getComputedStyle((document.body: any)).getPropertyValue(
94
- '--interaction-commit-size',
95
- ),
96
- 10,
97
- );
98
- const interactionLabelWidth = parseInt(
99
- getComputedStyle((document.body: any)).getPropertyValue(
100
- '--interaction-label-width',
101
- ),
102
- 10,
103
- );
90
+ const itemData = useMemo<ItemData>(() => {
91
+ const interactionCommitSize = parseInt(
92
+ getComputedStyle((document.body: any)).getPropertyValue(
93
+ '--interaction-commit-size',
94
+ ),
95
+ 10,
96
+ );
97
+ const interactionLabelWidth = parseInt(
98
+ getComputedStyle((document.body: any)).getPropertyValue(
99
+ '--interaction-label-width',
100
+ ),
101
+ 10,
102
+ );
103
105
- const labelWidth = Math.min(interactionLabelWidth, width / 5);
106
- const timelineWidth = width - labelWidth - interactionCommitSize;
104
+ const labelWidth = Math.min(interactionLabelWidth, width / 5);
105
+ const timelineWidth = width - labelWidth - interactionCommitSize;
106
108
- return {
109
- chartData,
110
- dataForRoot,
111
- labelWidth,
112
- scaleX: scale(0, chartData.lastInteractionTime, 0, timelineWidth),
113
- selectedInteractionID,
114
- selectCommitIndex,
115
- selectInteraction,
116
- selectTab,
117
- };
118
- },
119
- [
107
+ return {
108
chartData,
109
dataForRoot,
110
+ labelWidth,
111
+ scaleX: scale(0, chartData.lastInteractionTime, 0, timelineWidth),
112
selectedInteractionID,
113
selectCommitIndex,
114
selectInteraction,
115
selectTab,
126
- width,
127
- ],
128
- );
116
+ };
117
+ }, [
118
+ chartData,
119
+ dataForRoot,
120
+ selectedInteractionID,
121
+ selectCommitIndex,
122
+ selectInteraction,
123
+ selectTab,
124
+ width,
125
+ ]);
126
127
// If a commit contains no fibers with an actualDuration > 0,
128
// Display a fallback message.
packages/react-devtools-shared/src/devtools/views/Profiler/ProfilerContext.js
+4
-3
@@ -169,9 +169,10 @@ function ProfilerContextController({children}: Props) {
169
store,
170
]);
171
172
- const [isCommitFilterEnabled, setIsCommitFilterEnabled] = useLocalStorage<
173
- boolean,
174
- >('React::DevTools::isCommitFilterEnabled', false);
172
+ const [
173
+ isCommitFilterEnabled,
174
+ setIsCommitFilterEnabled,
175
+ ] = useLocalStorage<boolean>('React::DevTools::isCommitFilterEnabled', false);
176
const [minCommitDuration, setMinCommitDuration] = useLocalStorage<number>(
177
'minCommitDuration',
178
0,
packages/react-devtools-shared/src/devtools/views/Profiler/ProfilingImportExportButtons.js
+58
-64
@@ -33,36 +33,33 @@ export default function ProfilingImportExportButtons() {
33
34
const {dispatch: modalDialogDispatch} = useContext(ModalDialogContext);
35
36
- const downloadData = useCallback(
37
- () => {
38
- if (rootID === null) {
39
- return;
40
- }
36
+ const downloadData = useCallback(() => {
37
+ if (rootID === null) {
38
+ return;
39
+ }
40
42
- if (profilingData !== null && downloadRef.current !== null) {
43
- const profilingDataExport = prepareProfilingDataExport(profilingData);
44
- const date = new Date();
45
- const dateString = date
46
- .toLocaleDateString(undefined, {
47
- year: 'numeric',
48
- month: '2-digit',
49
- day: '2-digit',
50
- })
51
- .replace(/\//g, '-');
52
- const timeString = date
53
- .toLocaleTimeString(undefined, {
54
- hour12: false,
55
- })
56
- .replace(/:/g, '-');
57
- downloadFile(
58
- downloadRef.current,
59
- `profiling-data.${dateString}.${timeString}.json`,
60
- JSON.stringify(profilingDataExport, null, 2),
61
- );
62
- }
63
- },
64
- [rootID, profilingData],
65
- );
41
+ if (profilingData !== null && downloadRef.current !== null) {
42
+ const profilingDataExport = prepareProfilingDataExport(profilingData);
43
+ const date = new Date();
44
+ const dateString = date
45
+ .toLocaleDateString(undefined, {
46
+ year: 'numeric',
47
+ month: '2-digit',
48
+ day: '2-digit',
49
+ })
50
+ .replace(/\//g, '-');
51
+ const timeString = date
52
+ .toLocaleTimeString(undefined, {
53
+ hour12: false,
54
+ })
55
+ .replace(/:/g, '-');
56
+ downloadFile(
57
+ downloadRef.current,
58
+ `profiling-data.${dateString}.${timeString}.json`,
59
+ JSON.stringify(profilingDataExport, null, 2),
60
+ );
61
+ }
62
+ }, [rootID, profilingData]);
63
64
const uploadData = useCallback(() => {
65
if (inputRef.current !== null) {
@@ -70,41 +67,38 @@ export default function ProfilingImportExportButtons() {
67
}
68
}, []);
69
73
- const handleFiles = useCallback(
74
- () => {
75
- const input = inputRef.current;
76
- if (input !== null && input.files.length > 0) {
77
- const fileReader = new FileReader();
78
- fileReader.addEventListener('load', () => {
79
- try {
80
- const raw = ((fileReader.result: any): string);
81
- const profilingDataExport = ((JSON.parse(
82
- raw,
83
- ): any): ProfilingDataExport);
84
- profilerStore.profilingData = prepareProfilingDataFrontendFromExport(
85
- profilingDataExport,
86
- );
87
- } catch (error) {
88
- modalDialogDispatch({
89
- type: 'SHOW',
90
- title: 'Import failed',
91
- content: (
92
- <Fragment>
93
- <div>The profiling data you selected cannot be imported.</div>
94
- {error !== null && (
95
- <div className={styles.ErrorMessage}>{error.message}</div>
96
- )}
97
- </Fragment>
98
- ),
99
- });
100
- }
101
- });
102
- // TODO (profiling) Handle fileReader errors.
103
- fileReader.readAsText(input.files[0]);
104
- }
105
- },
106
- [modalDialogDispatch, profilerStore],
107
- );
70
+ const handleFiles = useCallback(() => {
71
+ const input = inputRef.current;
72
+ if (input !== null && input.files.length > 0) {
73
+ const fileReader = new FileReader();
74
+ fileReader.addEventListener('load', () => {
75
+ try {
76
+ const raw = ((fileReader.result: any): string);
77
+ const profilingDataExport = ((JSON.parse(
78
+ raw,
79
+ ): any): ProfilingDataExport);
80
+ profilerStore.profilingData = prepareProfilingDataFrontendFromExport(
81
+ profilingDataExport,
82
+ );
83
+ } catch (error) {
84
+ modalDialogDispatch({
85
+ type: 'SHOW',
86
+ title: 'Import failed',
87
+ content: (
88
+ <Fragment>
89
+ <div>The profiling data you selected cannot be imported.</div>
90
+ {error !== null && (
91
+ <div className={styles.ErrorMessage}>{error.message}</div>
92
+ )}
93
+ </Fragment>
94
+ ),
95
+ });
96
+ }
97
+ });
98
+ // TODO (profiling) Handle fileReader errors.
99
+ fileReader.readAsText(input.files[0]);
100
+ }
101
+ }, [modalDialogDispatch, profilerStore]);
102
103
return (
104
<Fragment>
packages/react-devtools-shared/src/devtools/views/Profiler/ReloadAndProfileButton.js
+12
-14
@@ -39,22 +39,20 @@ export default function ReloadAndProfileButton() {
39
}),
40
[store],
41
);
42
- const {recordChangeDescriptions, supportsReloadAndProfile} = useSubscription<
43
- SubscriptionData,
44
- >(subscription);
42
+ const {
43
+ recordChangeDescriptions,
44
+ supportsReloadAndProfile,
45
+ } = useSubscription<SubscriptionData>(subscription);
46
46
- const reloadAndProfile = useCallback(
47
- () => {
48
- // TODO If we want to support reload-and-profile for e.g. React Native,
49
- // we might need to also start profiling here before reloading the app (since DevTools itself isn't reloaded).
50
- // We'd probably want to do this before reloading though, to avoid sending a message on a disconnected port in the browser.
51
- // For now, let's just skip doing it entirely to avoid paying snapshot costs for data we don't need.
52
- // startProfiling();
47
+ const reloadAndProfile = useCallback(() => {
48
+ // TODO If we want to support reload-and-profile for e.g. React Native,
49
+ // we might need to also start profiling here before reloading the app (since DevTools itself isn't reloaded).
50
+ // We'd probably want to do this before reloading though, to avoid sending a message on a disconnected port in the browser.
51
+ // For now, let's just skip doing it entirely to avoid paying snapshot costs for data we don't need.
52
+ // startProfiling();
53
54
- bridge.send('reloadAndProfile', recordChangeDescriptions);
55
- },
56
- [bridge, recordChangeDescriptions],
57
- );
54
+ bridge.send('reloadAndProfile', recordChangeDescriptions);
55
+ }, [bridge, recordChangeDescriptions]);
56
57
if (!supportsReloadAndProfile) {
58
return null;
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js
+18
-24
@@ -87,17 +87,14 @@ function List({
87
const prevCommitIndexRef = useRef<number | null>(null);
88
89
// Make sure a newly selected snapshot is fully visible within the list.
90
- useEffect(
91
- () => {
92
- if (selectedFilteredCommitIndex !== prevCommitIndexRef.current) {
93
- prevCommitIndexRef.current = selectedFilteredCommitIndex;
94
- if (selectedFilteredCommitIndex !== null && listRef.current !== null) {
95
- listRef.current.scrollToItem(selectedFilteredCommitIndex);
96
- }
90
+ useEffect(() => {
91
+ if (selectedFilteredCommitIndex !== prevCommitIndexRef.current) {
92
+ prevCommitIndexRef.current = selectedFilteredCommitIndex;
93
+ if (selectedFilteredCommitIndex !== null && listRef.current !== null) {
94
+ listRef.current.scrollToItem(selectedFilteredCommitIndex);
95
}
98
- },
99
- [listRef, selectedFilteredCommitIndex],
100
- );
96
+ }
97
+ }, [listRef, selectedFilteredCommitIndex]);
98
99
// When the mouse is down, dragging over a commit should auto-select it.
100
// This provides a nice way for users to swipe across a range of commits to compare them.
@@ -108,21 +105,18 @@ function List({
105
const handleMouseUp = useCallback(() => {
106
setIsMouseDown(false);
107
}, []);
111
- useEffect(
112
- () => {
113
- if (divRef.current === null) {
114
- return () => {};
115
- }
108
+ useEffect(() => {
109
+ if (divRef.current === null) {
110
+ return () => {};
111
+ }
112
117
- // It's important to listen to the ownerDocument to support the browser extension.
118
- // Here we use portals to render individual tabs (e.g. Profiler),
119
- // and the root document might belong to a different window.
120
- const ownerDocument = divRef.current.ownerDocument;
121
- ownerDocument.addEventListener('mouseup', handleMouseUp);
122
- return () => ownerDocument.removeEventListener('mouseup', handleMouseUp);
123
- },
124
- [divRef, handleMouseUp],
125
- );
113
+ // It's important to listen to the ownerDocument to support the browser extension.
114
+ // Here we use portals to render individual tabs (e.g. Profiler),
115
+ // and the root document might belong to a different window.
116
+ const ownerDocument = divRef.current.ownerDocument;
117
+ ownerDocument.addEventListener('mouseup', handleMouseUp);
118
+ return () => ownerDocument.removeEventListener('mouseup', handleMouseUp);
119
+ }, [divRef, handleMouseUp]);
120
121
const itemSize = useMemo(
122
() => Math.max(minBarWidth, width / filteredCommitIndices.length),
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotSelector.js
+22
-31
@@ -55,19 +55,16 @@ export default function SnapshotSelector(_: Props) {
55
const numFilteredCommits = filteredCommitIndices.length;
56
57
// Map the (unfiltered) selected commit index to an index within the filtered data.
58
- const selectedFilteredCommitIndex = useMemo(
59
- () => {
60
- if (selectedCommitIndex !== null) {
61
- for (let i = 0; i < filteredCommitIndices.length; i++) {
62
- if (filteredCommitIndices[i] === selectedCommitIndex) {
63
- return i;
64
- }
58
+ const selectedFilteredCommitIndex = useMemo(() => {
59
+ if (selectedCommitIndex !== null) {
60
+ for (let i = 0; i < filteredCommitIndices.length; i++) {
61
+ if (filteredCommitIndices[i] === selectedCommitIndex) {
62
+ return i;
63
}
64
}
67
- return null;
68
- },
69
- [filteredCommitIndices, selectedCommitIndex],
70
- );
65
+ }
66
+ return null;
67
+ }, [filteredCommitIndices, selectedCommitIndex]);
68
69
// TODO (ProfilerContext) This should be managed by the context controller (reducer).
70
// It doesn't currently know about the filtered commits though (since it doesn't suspend).
@@ -93,26 +90,20 @@ export default function SnapshotSelector(_: Props) {
90
numFilteredCommits;
91
}
92
96
- const viewNextCommit = useCallback(
97
- () => {
98
- let nextCommitIndex = ((selectedFilteredCommitIndex: any): number) + 1;
99
- if (nextCommitIndex === filteredCommitIndices.length) {
100
- nextCommitIndex = 0;
101
- }
102
- selectCommitIndex(filteredCommitIndices[nextCommitIndex]);
103
- },
104
- [selectedFilteredCommitIndex, filteredCommitIndices, selectCommitIndex],
105
- );
106
- const viewPrevCommit = useCallback(
107
- () => {
108
- let nextCommitIndex = ((selectedFilteredCommitIndex: any): number) - 1;
109
- if (nextCommitIndex < 0) {
110
- nextCommitIndex = filteredCommitIndices.length - 1;
111
- }
112
- selectCommitIndex(filteredCommitIndices[nextCommitIndex]);
113
- },
114
- [selectedFilteredCommitIndex, filteredCommitIndices, selectCommitIndex],
115
- );
93
+ const viewNextCommit = useCallback(() => {
94
+ let nextCommitIndex = ((selectedFilteredCommitIndex: any): number) + 1;
95
+ if (nextCommitIndex === filteredCommitIndices.length) {
96
+ nextCommitIndex = 0;
97
+ }
98
+ selectCommitIndex(filteredCommitIndices[nextCommitIndex]);
99
+ }, [selectedFilteredCommitIndex, filteredCommitIndices, selectCommitIndex]);
100
+ const viewPrevCommit = useCallback(() => {
101
+ let nextCommitIndex = ((selectedFilteredCommitIndex: any): number) - 1;
102
+ if (nextCommitIndex < 0) {
103
+ nextCommitIndex = filteredCommitIndices.length - 1;
104
+ }
105
+ selectCommitIndex(filteredCommitIndices[nextCommitIndex]);
106
+ }, [selectedFilteredCommitIndex, filteredCommitIndices, selectCommitIndex]);
107
108
const handleKeyDown = useCallback(
109
event => {
packages/react-devtools-shared/src/devtools/views/Settings/ComponentsSettings.js
+6
-9
@@ -229,13 +229,10 @@ export default function ComponentsSettings(_: {||}) {
229
// The Store will avoid doing any expensive work unless they've changed.
230
// We just want to batch the work in the event that they do change.
231
const componentFiltersRef = useRef<Array<ComponentFilter>>(componentFilters);
232
- useEffect(
233
- () => {
234
- componentFiltersRef.current = componentFilters;
235
- return () => {};
236
- },
237
- [componentFilters],
238
- );
232
+ useEffect(() => {
233
+ componentFiltersRef.current = componentFilters;
234
+ return () => {};
235
+ }, [componentFilters]);
236
useEffect(
237
() => () => {
238
store.componentFilters = [...componentFiltersRef.current];
@@ -282,8 +279,8 @@ export default function ComponentsSettings(_: {||}) {
279
componentFilter.isValid === false
280
? 'Filter invalid'
281
: componentFilter.isEnabled
285
- ? 'Filter enabled'
286
- : 'Filter disabled'
282
+ ? 'Filter enabled'
283
+ : 'Filter disabled'
284
}>
285
<ToggleIcon
286
isEnabled={componentFilter.isEnabled}
packages/react-devtools-shared/src/devtools/views/Settings/SettingsContext.js
+59
-72
@@ -74,83 +74,70 @@ function SettingsContextController({
74
'React::DevTools::theme',
75
'auto',
76
);
77
- const [appendComponentStack, setAppendComponentStack] = useLocalStorage<
78
- boolean,
79
- >(LOCAL_STORAGE_SHOULD_PATCH_CONSOLE_KEY, true);
80
- const [traceUpdatesEnabled, setTraceUpdatesEnabled] = useLocalStorage<
81
- boolean,
82
- >(LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY, false);
77
+ const [
78
+ appendComponentStack,
79
+ setAppendComponentStack,
80
+ ] = useLocalStorage<boolean>(LOCAL_STORAGE_SHOULD_PATCH_CONSOLE_KEY, true);
81
+ const [
82
+ traceUpdatesEnabled,
83
+ setTraceUpdatesEnabled,
84
+ ] = useLocalStorage<boolean>(LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY, false);
85
84
- const documentElements = useMemo<DocumentElements>(
85
- () => {
86
- const array: Array<HTMLElement> = [
87
- ((document.documentElement: any): HTMLElement),
88
- ];
89
- if (componentsPortalContainer != null) {
90
- array.push(
91
- ((componentsPortalContainer.ownerDocument
92
- .documentElement: any): HTMLElement),
93
- );
94
- }
95
- if (profilerPortalContainer != null) {
96
- array.push(
97
- ((profilerPortalContainer.ownerDocument
98
- .documentElement: any): HTMLElement),
99
- );
100
- }
101
- return array;
102
- },
103
- [componentsPortalContainer, profilerPortalContainer],
104
- );
86
+ const documentElements = useMemo<DocumentElements>(() => {
87
+ const array: Array<HTMLElement> = [
88
+ ((document.documentElement: any): HTMLElement),
89
+ ];
90
+ if (componentsPortalContainer != null) {
91
+ array.push(
92
+ ((componentsPortalContainer.ownerDocument
93
+ .documentElement: any): HTMLElement),
94
+ );
95
+ }
96
+ if (profilerPortalContainer != null) {
97
+ array.push(
98
+ ((profilerPortalContainer.ownerDocument
99
+ .documentElement: any): HTMLElement),
100
+ );
101
+ }
102
+ return array;
103
+ }, [componentsPortalContainer, profilerPortalContainer]);
104
106
- useLayoutEffect(
107
- () => {
108
- switch (displayDensity) {
109
- case 'comfortable':
110
- updateDisplayDensity('comfortable', documentElements);
111
- break;
112
- case 'compact':
113
- updateDisplayDensity('compact', documentElements);
114
- break;
115
- default:
116
- throw Error(`Unsupported displayDensity value "${displayDensity}"`);
117
- }
118
- },
119
- [displayDensity, documentElements],
120
- );
105
+ useLayoutEffect(() => {
106
+ switch (displayDensity) {
107
+ case 'comfortable':
108
+ updateDisplayDensity('comfortable', documentElements);
109
+ break;
110
+ case 'compact':
111
+ updateDisplayDensity('compact', documentElements);
112
+ break;
113
+ default:
114
+ throw Error(`Unsupported displayDensity value "${displayDensity}"`);
115
+ }
116
+ }, [displayDensity, documentElements]);
117
122
- useLayoutEffect(
123
- () => {
124
- switch (theme) {
125
- case 'light':
126
- updateThemeVariables('light', documentElements);
127
- break;
128
- case 'dark':
129
- updateThemeVariables('dark', documentElements);
130
- break;
131
- case 'auto':
132
- updateThemeVariables(browserTheme, documentElements);
133
- break;
134
- default:
135
- throw Error(`Unsupported theme value "${theme}"`);
136
- }
137
- },
138
- [browserTheme, theme, documentElements],
139
- );
118
+ useLayoutEffect(() => {
119
+ switch (theme) {
120
+ case 'light':
121
+ updateThemeVariables('light', documentElements);
122
+ break;
123
+ case 'dark':
124
+ updateThemeVariables('dark', documentElements);
125
+ break;
126
+ case 'auto':
127
+ updateThemeVariables(browserTheme, documentElements);
128
+ break;
129
+ default:
130
+ throw Error(`Unsupported theme value "${theme}"`);
131
+ }
132
+ }, [browserTheme, theme, documentElements]);
133
141
- useEffect(
142
- () => {
143
- bridge.send('updateAppendComponentStack', appendComponentStack);
144
- },
145
- [bridge, appendComponentStack],
146
- );
134
+ useEffect(() => {
135
+ bridge.send('updateAppendComponentStack', appendComponentStack);
136
+ }, [bridge, appendComponentStack]);
137
148
- useEffect(
149
- () => {
150
- bridge.send('setTraceUpdatesEnabled', traceUpdatesEnabled);
151
- },
152
- [bridge, traceUpdatesEnabled],
153
- );
138
+ useEffect(() => {
139
+ bridge.send('setTraceUpdatesEnabled', traceUpdatesEnabled);
140
+ }, [bridge, traceUpdatesEnabled]);
141
142
const value = useMemo(
143
() => ({
packages/react-devtools-shared/src/devtools/views/Settings/SettingsModal.js
+5
-8
@@ -75,14 +75,11 @@ function SettingsModalImpl(_: {||}) {
75
const modalRef = useRef<HTMLDivElement | null>(null);
76
useModalDismissSignal(modalRef, dismissModal);
77
78
- useEffect(
79
- () => {
80
- if (modalRef.current !== null) {
81
- modalRef.current.focus();
82
- }
83
- },
84
- [modalRef],
85
- );
78
+ useEffect(() => {
79
+ if (modalRef.current !== null) {
80
+ modalRef.current.focus();
81
+ }
82
+ }, [modalRef]);
83
84
let view = null;
85
switch (selectedTabID) {
packages/react-devtools-shared/src/devtools/views/UnsupportedVersionDialog.js
+25
-27
@@ -22,35 +22,32 @@ export default function UnsupportedVersionDialog(_: {||}) {
22
const store = useContext(StoreContext);
23
const [state, setState] = useState<DAILOG_STATE>('dialog-not-shown');
24
25
- useEffect(
26
- () => {
27
- if (state === 'dialog-not-shown') {
28
- const showDialog = () => {
29
- batchedUpdates(() => {
30
- setState('show-dialog');
31
- dispatch({
32
- canBeDismissed: true,
33
- type: 'SHOW',
34
- content: <DialogContent />,
35
- });
25
+ useEffect(() => {
26
+ if (state === 'dialog-not-shown') {
27
+ const showDialog = () => {
28
+ batchedUpdates(() => {
29
+ setState('show-dialog');
30
+ dispatch({
31
+ canBeDismissed: true,
32
+ type: 'SHOW',
33
+ content: <DialogContent />,
34
});
37
- };
35
+ });
36
+ };
37
39
- if (store.unsupportedRendererVersionDetected) {
40
- showDialog();
41
- } else {
42
- store.addListener('unsupportedRendererVersionDetected', showDialog);
43
- return () => {
44
- store.removeListener(
45
- 'unsupportedRendererVersionDetected',
46
- showDialog,
47
- );
48
- };
49
- }
38
+ if (store.unsupportedRendererVersionDetected) {
39
+ showDialog();
40
+ } else {
41
+ store.addListener('unsupportedRendererVersionDetected', showDialog);
42
+ return () => {
43
+ store.removeListener(
44
+ 'unsupportedRendererVersionDetected',
45
+ showDialog,
46
+ );
47
+ };
48
}
51
- },
52
- [state, store],
53
- );
49
+ }
50
+ }, [state, store]);
51
52
return null;
53
}
@@ -74,7 +71,8 @@ function DialogContent(_: {||}) {
71
rel="noopener noreferrer"
72
href={UNSUPPORTED_VERSION_URL}>
73
install an older version of the extension
77
- </a>.
74
+ </a>
75
+ .
76
</p>
77
</div>
78
</div>
packages/react-devtools-shared/src/devtools/views/WarnIfLegacyBackendDetected.js
+46
-49
@@ -20,58 +20,55 @@ export default function WarnIfLegacyBackendDetected(_: {||}) {
20
// Detect pairing with legacy v3 backend.
21
// We do this by listening to a message that it broadcasts but the v4 backend doesn't.
22
// In this case the frontend should show upgrade instructions.
23
- useEffect(
24
- () => {
25
- // Wall.listen returns a cleanup function
26
- let unlisten = bridge.wall.listen(message => {
27
- switch (message.type) {
28
- case 'call':
29
- case 'event':
30
- case 'many-events':
31
- // Any of these types indicate the v3 backend.
32
- dispatch({
33
- canBeDismissed: false,
34
- type: 'SHOW',
35
- title: 'DevTools v4 is incompatible with this version of React',
36
- content: <InvalidBackendDetected />,
37
- });
23
+ useEffect(() => {
24
+ // Wall.listen returns a cleanup function
25
+ let unlisten = bridge.wall.listen(message => {
26
+ switch (message.type) {
27
+ case 'call':
28
+ case 'event':
29
+ case 'many-events':
30
+ // Any of these types indicate the v3 backend.
31
+ dispatch({
32
+ canBeDismissed: false,
33
+ type: 'SHOW',
34
+ title: 'DevTools v4 is incompatible with this version of React',
35
+ content: <InvalidBackendDetected />,
36
+ });
37
39
- // Once we've identified the backend version, it's safe to unsubscribe.
40
- if (typeof unlisten === 'function') {
41
- unlisten();
42
- unlisten = null;
43
- }
44
- break;
45
- default:
46
- break;
47
- }
38
+ // Once we've identified the backend version, it's safe to unsubscribe.
39
+ if (typeof unlisten === 'function') {
40
+ unlisten();
41
+ unlisten = null;
42
+ }
43
+ break;
44
+ default:
45
+ break;
46
+ }
47
49
- switch (message.event) {
50
- case 'isBackendStorageAPISupported':
51
- case 'isNativeStyleEditorSupported':
52
- case 'operations':
53
- case 'overrideComponentFilters':
54
- // Any of these is sufficient to indicate a v4 backend.
55
- // Once we've identified the backend version, it's safe to unsubscribe.
56
- if (typeof unlisten === 'function') {
57
- unlisten();
58
- unlisten = null;
59
- }
60
- break;
61
- default:
62
- break;
63
- }
64
- });
48
+ switch (message.event) {
49
+ case 'isBackendStorageAPISupported':
50
+ case 'isNativeStyleEditorSupported':
51
+ case 'operations':
52
+ case 'overrideComponentFilters':
53
+ // Any of these is sufficient to indicate a v4 backend.
54
+ // Once we've identified the backend version, it's safe to unsubscribe.
55
+ if (typeof unlisten === 'function') {
56
+ unlisten();
57
+ unlisten = null;
58
+ }
59
+ break;
60
+ default:
61
+ break;
62
+ }
63
+ });
64
66
- return () => {
67
- if (typeof unlisten === 'function') {
68
- unlisten();
69
- unlisten = null;
70
- }
71
- };
72
- },
73
- [bridge, dispatch],
74
- );
65
+ return () => {
66
+ if (typeof unlisten === 'function') {
67
+ unlisten();
68
+ unlisten = null;
69
+ }
70
+ };
71
+ }, [bridge, dispatch]);
72
73
return null;
74
}
packages/react-devtools-shared/src/devtools/views/hooks.js
+106
-121
@@ -112,30 +112,27 @@ export function useIsOverflowing(
112
const [isOverflowing, setIsOverflowing] = useState<boolean>(false);
113
114
// It's important to use a layout effect, so that we avoid showing a flash of overflowed content.
115
- useLayoutEffect(
116
- () => {
117
- if (containerRef.current === null) {
118
- return () => {};
119
- }
115
+ useLayoutEffect(() => {
116
+ if (containerRef.current === null) {
117
+ return () => {};
118
+ }
119
121
- const container = ((containerRef.current: any): HTMLDivElement);
120
+ const container = ((containerRef.current: any): HTMLDivElement);
121
123
- const handleResize = throttle(
124
- () => setIsOverflowing(container.clientWidth <= totalChildWidth),
125
- 100,
126
- );
122
+ const handleResize = throttle(
123
+ () => setIsOverflowing(container.clientWidth <= totalChildWidth),
124
+ 100,
125
+ );
126
128
- handleResize();
127
+ handleResize();
128
130
- // It's important to listen to the ownerDocument.defaultView to support the browser extension.
131
- // Here we use portals to render individual tabs (e.g. Profiler),
132
- // and the root document might belong to a different window.
133
- const ownerWindow = container.ownerDocument.defaultView;
134
- ownerWindow.addEventListener('resize', handleResize);
135
- return () => ownerWindow.removeEventListener('resize', handleResize);
136
- },
137
- [containerRef, totalChildWidth],
138
- );
129
+ // It's important to listen to the ownerDocument.defaultView to support the browser extension.
130
+ // Here we use portals to render individual tabs (e.g. Profiler),
131
+ // and the root document might belong to a different window.
132
+ const ownerWindow = container.ownerDocument.defaultView;
133
+ ownerWindow.addEventListener('resize', handleResize);
134
+ return () => ownerWindow.removeEventListener('resize', handleResize);
135
+ }, [containerRef, totalChildWidth]);
136
137
return isOverflowing;
138
}
@@ -145,24 +142,21 @@ export function useLocalStorage<T>(
142
key: string,
143
initialValue: T | (() => T),
144
): [T, (value: T | (() => T)) => void] {
148
- const getValueFromLocalStorage = useCallback(
149
- () => {
150
- try {
151
- const item = localStorageGetItem(key);
152
- if (item != null) {
153
- return JSON.parse(item);
154
- }
155
- } catch (error) {
156
- console.log(error);
157
- }
158
- if (typeof initialValue === 'function') {
159
- return ((initialValue: any): () => T)();
160
- } else {
161
- return initialValue;
145
+ const getValueFromLocalStorage = useCallback(() => {
146
+ try {
147
+ const item = localStorageGetItem(key);
148
+ if (item != null) {
149
+ return JSON.parse(item);
150
}
163
- },
164
- [initialValue, key],
165
- );
151
+ } catch (error) {
152
+ console.log(error);
153
+ }
154
+ if (typeof initialValue === 'function') {
155
+ return ((initialValue: any): () => T)();
156
+ } else {
157
+ return initialValue;
158
+ }
159
+ }, [initialValue, key]);
160
161
const [storedValue, setStoredValue] = useState(getValueFromLocalStorage);
162
@@ -182,23 +176,20 @@ export function useLocalStorage<T>(
176
177
// Listen for changes to this local storage value made from other windows.
178
// This enables the e.g. "⚛️ Elements" tab to update in response to changes from "⚛️ Settings".
185
- useLayoutEffect(
186
- () => {
187
- const onStorage = event => {
188
- const newValue = getValueFromLocalStorage();
189
- if (key === event.key && storedValue !== newValue) {
190
- setValue(newValue);
191
- }
192
- };
179
+ useLayoutEffect(() => {
180
+ const onStorage = event => {
181
+ const newValue = getValueFromLocalStorage();
182
+ if (key === event.key && storedValue !== newValue) {
183
+ setValue(newValue);
184
+ }
185
+ };
186
194
- window.addEventListener('storage', onStorage);
187
+ window.addEventListener('storage', onStorage);
188
196
- return () => {
197
- window.removeEventListener('storage', onStorage);
198
- };
199
- },
200
- [getValueFromLocalStorage, key, storedValue, setValue],
201
- );
189
+ return () => {
190
+ window.removeEventListener('storage', onStorage);
191
+ };
192
+ }, [getValueFromLocalStorage, key, storedValue, setValue]);
193
194
return [storedValue, setValue];
195
}
@@ -208,47 +199,44 @@ export function useModalDismissSignal(
199
dismissCallback: () => void,
200
dismissOnClickOutside?: boolean = true,
201
): void {
211
- useEffect(
212
- () => {
213
- if (modalRef.current === null) {
214
- return () => {};
215
- }
216
-
217
- const handleDocumentKeyDown = ({key}: any) => {
218
- if (key === 'Escape') {
219
- dismissCallback();
220
- }
221
- };
222
-
223
- const handleDocumentClick = (event: any) => {
224
- // $FlowFixMe
225
- if (
226
- modalRef.current !== null &&
227
- !modalRef.current.contains(event.target)
228
- ) {
229
- event.stopPropagation();
230
- event.preventDefault();
231
-
232
- dismissCallback();
233
- }
234
- };
202
+ useEffect(() => {
203
+ if (modalRef.current === null) {
204
+ return () => {};
205
+ }
206
236
- // It's important to listen to the ownerDocument to support the browser extension.
237
- // Here we use portals to render individual tabs (e.g. Profiler),
238
- // and the root document might belong to a different window.
239
- const ownerDocument = modalRef.current.ownerDocument;
240
- ownerDocument.addEventListener('keydown', handleDocumentKeyDown);
241
- if (dismissOnClickOutside) {
242
- ownerDocument.addEventListener('click', handleDocumentClick);
207
+ const handleDocumentKeyDown = ({key}: any) => {
208
+ if (key === 'Escape') {
209
+ dismissCallback();
210
+ }
211
+ };
212
+
213
+ const handleDocumentClick = (event: any) => {
214
+ // $FlowFixMe
215
+ if (
216
+ modalRef.current !== null &&
217
+ !modalRef.current.contains(event.target)
218
+ ) {
219
+ event.stopPropagation();
220
+ event.preventDefault();
221
+
222
+ dismissCallback();
223
}
224
+ };
225
+
226
+ // It's important to listen to the ownerDocument to support the browser extension.
227
+ // Here we use portals to render individual tabs (e.g. Profiler),
228
+ // and the root document might belong to a different window.
229
+ const ownerDocument = modalRef.current.ownerDocument;
230
+ ownerDocument.addEventListener('keydown', handleDocumentKeyDown);
231
+ if (dismissOnClickOutside) {
232
+ ownerDocument.addEventListener('click', handleDocumentClick);
233
+ }
234
245
- return () => {
246
- ownerDocument.removeEventListener('keydown', handleDocumentKeyDown);
247
- ownerDocument.removeEventListener('click', handleDocumentClick);
248
- };
249
- },
250
- [modalRef, dismissCallback, dismissOnClickOutside],
251
- );
235
+ return () => {
236
+ ownerDocument.removeEventListener('keydown', handleDocumentKeyDown);
237
+ ownerDocument.removeEventListener('click', handleDocumentClick);
238
+ };
239
+ }, [modalRef, dismissCallback, dismissOnClickOutside]);
240
}
241
242
// Copied from https://github.com/facebook/react/pull/15022
@@ -276,42 +264,39 @@ export function useSubscription<Value>({
264
});
265
}
266
279
- useEffect(
280
- () => {
281
- let didUnsubscribe = false;
267
+ useEffect(() => {
268
+ let didUnsubscribe = false;
269
283
- const checkForUpdates = () => {
284
- if (didUnsubscribe) {
285
- return;
270
+ const checkForUpdates = () => {
271
+ if (didUnsubscribe) {
272
+ return;
273
+ }
274
+
275
+ setState(prevState => {
276
+ if (
277
+ prevState.getCurrentValue !== getCurrentValue ||
278
+ prevState.subscribe !== subscribe
279
+ ) {
280
+ return prevState;
281
}
282
288
- setState(prevState => {
289
- if (
290
- prevState.getCurrentValue !== getCurrentValue ||
291
- prevState.subscribe !== subscribe
292
- ) {
293
- return prevState;
294
- }
295
-
296
- const value = getCurrentValue();
297
- if (prevState.value === value) {
298
- return prevState;
299
- }
300
-
301
- return {...prevState, value};
302
- });
303
- };
304
- const unsubscribe = subscribe(checkForUpdates);
283
+ const value = getCurrentValue();
284
+ if (prevState.value === value) {
285
+ return prevState;
286
+ }
287
306
- checkForUpdates();
288
+ return {...prevState, value};
289
+ });
290
+ };
291
+ const unsubscribe = subscribe(checkForUpdates);
292
308
- return () => {
309
- didUnsubscribe = true;
310
- unsubscribe();
311
- };
312
- },
313
- [getCurrentValue, subscribe],
314
- );
293
+ checkForUpdates();
294
+
295
+ return () => {
296
+ didUnsubscribe = true;
297
+ unsubscribe();
298
+ };
299
+ }, [getCurrentValue, subscribe]);
300
301
return state.value;
302
}
packages/react-devtools-shell/src/app/Hydration/index.js
+10
-2
@@ -17,8 +17,16 @@ typedArray[1] = 2;
17
typedArray[2] = 3;
18
19
const arrayOfArrays = [
20
- [['a', 'b', 'c'], ['d', 'e', 'f'], ['h', 'i', 'j']],
21
- [['k', 'l', 'm'], ['n', 'o', 'p'], ['q', 'r', 's']],
20
+ [
21
+ ['a', 'b', 'c'],
22
+ ['d', 'e', 'f'],
23
+ ['h', 'i', 'j'],
24
+ ],
25
+ [
26
+ ['k', 'l', 'm'],
27
+ ['n', 'o', 'p'],
28
+ ['q', 'r', 's'],
29
+ ],
30
[['t', 'u', 'v'], ['w', 'x', 'y'], ['z']],
31
[],
32
];
packages/react-devtools-shell/src/app/InspectableElements/UnserializableProps.js
+8
-2
@@ -11,9 +11,15 @@ import React from 'react';
11
import Immutable from 'immutable';
12
13
const set = new Set(['abc', 123]);
14
-const map = new Map([['name', 'Brian'], ['food', 'sushi']]);
14
+const map = new Map([
15
+ ['name', 'Brian'],
16
+ ['food', 'sushi'],
17
+]);
18
const setOfSets = new Set([new Set(['a', 'b', 'c']), new Set([1, 2, 3])]);
16
-const mapOfMaps = new Map([['first', map], ['second', map]]);
19
+const mapOfMaps = new Map([
20
+ ['first', map],
21
+ ['second', map],
22
+]);
23
const typedArray = Int8Array.from([100, -100, 0]);
24
const arrayBuffer = typedArray.buffer;
25
const dataView = new DataView(arrayBuffer);
packages/react-devtools-shell/src/app/InteractionTracing/index.js
+39
-51
@@ -18,66 +18,54 @@ export default function InteractionTracing() {
18
const [count, setCount] = useState(0);
19
const [shouldCascade, setShouldCascade] = useState(false);
20
21
- const handleUpdate = useCallback(
22
- () => {
23
- trace('count', performance.now(), () => {
24
- setTimeout(
25
- wrap(() => {
21
+ const handleUpdate = useCallback(() => {
22
+ trace('count', performance.now(), () => {
23
+ setTimeout(
24
+ wrap(() => {
25
+ setCount(count + 1);
26
+ }),
27
+ count * 100,
28
+ );
29
+ });
30
+ }, [count]);
31
+
32
+ const handleCascadingUpdate = useCallback(() => {
33
+ trace('cascade', performance.now(), () => {
34
+ setTimeout(
35
+ wrap(() => {
36
+ batchedUpdates(() => {
37
setCount(count + 1);
27
- }),
28
- count * 100,
29
- );
30
- });
31
- },
32
- [count],
33
- );
38
+ setShouldCascade(true);
39
+ });
40
+ }),
41
+ count * 100,
42
+ );
43
+ });
44
+ }, [count]);
45
35
- const handleCascadingUpdate = useCallback(
36
- () => {
37
- trace('cascade', performance.now(), () => {
46
+ const handleMultiple = useCallback(() => {
47
+ trace('first', performance.now(), () => {
48
+ trace('second', performance.now(), () => {
49
setTimeout(
50
wrap(() => {
40
- batchedUpdates(() => {
41
- setCount(count + 1);
42
- setShouldCascade(true);
43
- });
51
+ setCount(count + 1);
52
}),
53
count * 100,
54
);
55
});
48
- },
49
- [count],
50
- );
56
+ });
57
+ }, [count]);
58
52
- const handleMultiple = useCallback(
53
- () => {
54
- trace('first', performance.now(), () => {
55
- trace('second', performance.now(), () => {
56
- setTimeout(
57
- wrap(() => {
58
- setCount(count + 1);
59
- }),
60
- count * 100,
61
- );
62
- });
63
- });
64
- },
65
- [count],
66
- );
67
-
68
- useEffect(
69
- () => {
70
- if (shouldCascade) {
71
- setTimeout(
72
- wrap(() => {
73
- setShouldCascade(false);
74
- }),
75
- count * 100,
76
- );
77
- }
78
- },
79
- [count, shouldCascade],
80
- );
59
+ useEffect(() => {
60
+ if (shouldCascade) {
61
+ setTimeout(
62
+ wrap(() => {
63
+ setShouldCascade(false);
64
+ }),
65
+ count * 100,
66
+ );
67
+ }
68
+ }, [count, shouldCascade]);
69
70
return (
71
<Fragment>
packages/react-devtools-shell/src/app/ToDoList/List.js
+14
-17
@@ -28,23 +28,20 @@ export default function List(props: Props) {
28
]);
29
const [uid, setUID] = useState<number>(4);
30
31
- const handleClick = useCallback(
32
- () => {
33
- if (newItemText !== '') {
34
- setItems([
35
- ...items,
36
- {
37
- id: uid,
38
- isComplete: false,
39
- text: newItemText,
40
- },
41
- ]);
42
- setUID(uid + 1);
43
- setNewItemText('');
44
- }
45
- },
46
- [newItemText, items, uid],
47
- );
31
+ const handleClick = useCallback(() => {
32
+ if (newItemText !== '') {
33
+ setItems([
34
+ ...items,
35
+ {
36
+ id: uid,
37
+ isComplete: false,
38
+ text: newItemText,
39
+ },
40
+ ]);
41
+ setUID(uid + 1);
42
+ setNewItemText('');
43
+ }
44
+ }, [newItemText, items, uid]);
45
46
const handleKeyPress = useCallback(
47
event => {
packages/react-devtools-shell/src/app/ToDoList/ListItem.js
+6
-12
@@ -19,19 +19,13 @@ type Props = {|
19
|};
20
21
function ListItem({item, removeItem, toggleItem}: Props) {
22
- const handleDelete = useCallback(
23
- () => {
24
- removeItem(item);
25
- },
26
- [item, removeItem],
27
- );
22
+ const handleDelete = useCallback(() => {
23
+ removeItem(item);
24
+ }, [item, removeItem]);
25
29
- const handleToggle = useCallback(
30
- () => {
31
- toggleItem(item);
32
- },
33
- [item, toggleItem],
34
- );
26
+ const handleToggle = useCallback(() => {
27
+ toggleItem(item);
28
+ }, [item, toggleItem]);
29
30
return (
31
<li className={styles.ListItem}>
packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
+7
-9
@@ -1148,9 +1148,11 @@ describe('ReactComponentLifeCycle', () => {
1148
render() {
1149
childInstance = this;
1150
return (
1151
- <div onClick={this.updateState} ref={divRef}>{`remote:${
1152
- this.state.remote
1153
- }, local:${this.state.local}`}</div>
1151
+ <div
1152
+ onClick={this.updateState}
1153
+ ref={
1154
+ divRef
1155
+ }>{`remote:${this.state.remote}, local:${this.state.local}`}</div>
1156
);
1157
}
1158
}
@@ -1197,17 +1199,13 @@ describe('ReactComponentLifeCycle', () => {
1199
}
1200
getSnapshotBeforeUpdate(prevProps, prevState) {
1201
log.push(
1200
- `getSnapshotBeforeUpdate() prevProps:${prevProps.value} prevState:${
1201
- prevState.value
1202
- }`,
1202
+ `getSnapshotBeforeUpdate() prevProps:${prevProps.value} prevState:${prevState.value}`,
1203
);
1204
return 'abc';
1205
}
1206
componentDidUpdate(prevProps, prevState, snapshot) {
1207
log.push(
1208
- `componentDidUpdate() prevProps:${prevProps.value} prevState:${
1209
- prevState.value
1210
- } snapshot:${snapshot}`,
1208
+ `componentDidUpdate() prevProps:${prevProps.value} prevState:${prevState.value} snapshot:${snapshot}`,
1209
);
1210
}
1211
render() {
packages/react-dom/src/__tests__/ReactCompositeComponent-test.js
+3
-1
@@ -165,7 +165,9 @@ describe('ReactCompositeComponent', () => {
165
// Old API based on heuristic
166
let container = document.createElement('div');
167
container.innerHTML = markup;
168
- expect(() => ReactDOM.render(<Parent />, container)).toWarnDev(
168
+ expect(() =>
169
+ ReactDOM.render(<Parent />, container),
170
+ ).toWarnDev(
171
'render(): Calling ReactDOM.render() to hydrate server-rendered markup ' +
172
'will stop working in React v17. Replace the ReactDOM.render() call ' +
173
'with ReactDOM.hydrate() if you want React to attach to the server HTML.',
packages/react-dom/src/__tests__/ReactDOMComponent-test.js
+3
-6
@@ -182,24 +182,21 @@ describe('ReactDOMComponent', () => {
182
it('should warn for unknown string event handlers', () => {
183
const container = document.createElement('div');
184
expect(() =>
185
- ReactDOM.render(<div onUnknown="alert("hack")" />, container),
185
+ ReactDOM.render(<div onUnknown='alert("hack")' />, container),
186
).toErrorDev(
187
'Warning: Unknown event handler property `onUnknown`. It will be ignored.\n in div (at **)',
188
);
189
expect(container.firstChild.hasAttribute('onUnknown')).toBe(false);
190
expect(container.firstChild.onUnknown).toBe(undefined);
191
expect(() =>
192
- ReactDOM.render(<div onunknown="alert("hack")" />, container),
192
+ ReactDOM.render(<div onunknown='alert("hack")' />, container),
193
).toErrorDev(
194
'Warning: Unknown event handler property `onunknown`. It will be ignored.\n in div (at **)',
195
);
196
expect(container.firstChild.hasAttribute('onunknown')).toBe(false);
197
expect(container.firstChild.onunknown).toBe(undefined);
198
expect(() =>
199
- ReactDOM.render(
200
- <div on-unknown="alert("hack")" />,
201
- container,
202
- ),
199
+ ReactDOM.render(<div on-unknown='alert("hack")' />, container),
200
).toErrorDev(
201
'Warning: Unknown event handler property `on-unknown`. It will be ignored.\n in div (at **)',
202
);
packages/react-dom/src/__tests__/ReactDOMComponentTree-test.js
+6
-2
@@ -190,7 +190,9 @@ describe('ReactDOMComponentTree', () => {
190
it('finds instance of node that is attempted to be unmounted', () => {
191
const component = <div />;
192
const node = ReactDOM.render(<div>{component}</div>, container);
193
- expect(() => ReactDOM.unmountComponentAtNode(node)).toErrorDev(
193
+ expect(() =>
194
+ ReactDOM.unmountComponentAtNode(node),
195
+ ).toErrorDev(
196
"unmountComponentAtNode(): The node you're attempting to unmount " +
197
'was rendered by React and is not a top-level container. You may ' +
198
'have accidentally passed in a React root node instead of its ' +
@@ -207,7 +209,9 @@ describe('ReactDOMComponentTree', () => {
209
);
210
const anotherComponent = <div />;
211
const instance = ReactDOM.render(component, container);
210
- expect(() => ReactDOM.render(anotherComponent, instance)).toErrorDev(
212
+ expect(() =>
213
+ ReactDOM.render(anotherComponent, instance),
214
+ ).toErrorDev(
215
'render(...): Replacing React-rendered children with a new root ' +
216
'component. If you intended to update the children of this node, ' +
217
'you should instead have the existing children update their state ' +
packages/react-dom/src/__tests__/ReactDOMFiber-test.js
+6
-2
@@ -1151,7 +1151,9 @@ describe('ReactDOMFiber', () => {
1151
expect(container.innerHTML).toBe('<div>bar</div>');
1152
// then we mess with the DOM before an update
1153
container.innerHTML = '<div>MEOW.</div>';
1154
- expect(() => ReactDOM.render(<div>baz</div>, container)).toErrorDev(
1154
+ expect(() =>
1155
+ ReactDOM.render(<div>baz</div>, container),
1156
+ ).toErrorDev(
1157
'render(...): ' +
1158
'It looks like the React-rendered content of this container was ' +
1159
'removed without using React. This is not supported and will ' +
@@ -1168,7 +1170,9 @@ describe('ReactDOMFiber', () => {
1170
expect(container.innerHTML).toBe('<div>bar</div>');
1171
// then we mess with the DOM before an update
1172
container.innerHTML = '';
1171
- expect(() => ReactDOM.render(<div>baz</div>, container)).toErrorDev(
1173
+ expect(() =>
1174
+ ReactDOM.render(<div>baz</div>, container),
1175
+ ).toErrorDev(
1176
'render(...): ' +
1177
'It looks like the React-rendered content of this container was ' +
1178
'removed without using React. This is not supported and will ' +
packages/react-dom/src/__tests__/ReactDOMFiberAsync-test.internal.js
+5
-8
@@ -593,14 +593,11 @@ describe('ReactDOMFiberAsync', () => {
593
594
function App({label}) {
595
const [step, setStep] = useState(0);
596
- useEffect(
597
- () => {
598
- if (step < 3) {
599
- setStep(step + 1);
600
- }
601
- },
602
- [step],
603
- );
596
+ useEffect(() => {
597
+ if (step < 3) {
598
+ setStep(step + 1);
599
+ }
600
+ }, [step]);
601
602
// The component should keep re-rendering itself until `step` is 3.
603
return step === 3 ? 'Finished' : 'Unresolved';
packages/react-dom/src/__tests__/ReactDOMServerIntegrationAttributes-test.js
+1
-4
@@ -636,10 +636,7 @@ describe('ReactDOMServerIntegration', () => {
636
});
637
638
itRenders('no unknown events', async render => {
639
- const e = await render(
640
- <div onunknownevent="alert("hack")" />,
641
- 1,
642
- );
639
+ const e = await render(<div onunknownevent='alert("hack")' />, 1);
640
expect(e.getAttribute('onunknownevent')).toBe(null);
641
});
642
packages/react-dom/src/__tests__/ReactDOMServerIntegrationElements-test.js
+22
-17
@@ -258,8 +258,7 @@ describe('ReactDOMServerIntegration', () => {
258
<div>
259
{[['a'], 'b']}
260
<div>
261
- <X key="1" />
262
- d
261
+ <X key="1" />d
262
</div>
263
e
264
</div>,
@@ -493,11 +492,13 @@ describe('ReactDOMServerIntegration', () => {
492
// Put dangerouslySetInnerHTML one level deeper because otherwise
493
// hydrating from a bad markup would cause a mismatch (since we don't
494
// patch dangerouslySetInnerHTML as text content).
496
- const e = (await render(
497
- <div>
498
- <span dangerouslySetInnerHTML={{__html: 0}} />
499
- </div>,
500
- )).firstChild;
495
+ const e = (
496
+ await render(
497
+ <div>
498
+ <span dangerouslySetInnerHTML={{__html: 0}} />
499
+ </div>,
500
+ )
501
+ ).firstChild;
502
expect(e.childNodes.length).toBe(1);
503
expect(e.firstChild.nodeType).toBe(TEXT_NODE_TYPE);
504
expect(e.textContent).toBe('0');
@@ -507,11 +508,13 @@ describe('ReactDOMServerIntegration', () => {
508
// Put dangerouslySetInnerHTML one level deeper because otherwise
509
// hydrating from a bad markup would cause a mismatch (since we don't
510
// patch dangerouslySetInnerHTML as text content).
510
- const e = (await render(
511
- <div>
512
- <span dangerouslySetInnerHTML={{__html: false}} />
513
- </div>,
514
- )).firstChild;
511
+ const e = (
512
+ await render(
513
+ <div>
514
+ <span dangerouslySetInnerHTML={{__html: false}} />
515
+ </div>,
516
+ )
517
+ ).firstChild;
518
expect(e.childNodes.length).toBe(1);
519
expect(e.firstChild.nodeType).toBe(TEXT_NODE_TYPE);
520
expect(e.firstChild.data).toBe('false');
@@ -523,11 +526,13 @@ describe('ReactDOMServerIntegration', () => {
526
// Put dangerouslySetInnerHTML one level deeper because otherwise
527
// hydrating from a bad markup would cause a mismatch (since we don't
528
// patch dangerouslySetInnerHTML as text content).
526
- const e = (await render(
527
- <div>
528
- <span dangerouslySetInnerHTML={{__html: 'hello'}} />
529
- </div>,
530
- )).firstChild;
529
+ const e = (
530
+ await render(
531
+ <div>
532
+ <span dangerouslySetInnerHTML={{__html: 'hello'}} />
533
+ </div>,
534
+ )
535
+ ).firstChild;
536
expect(e.childNodes.length).toBe(1);
537
expect(e.firstChild.nodeType).toBe(TEXT_NODE_TYPE);
538
expect(e.textContent).toBe('hello');
packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.internal.js
+12
-21
@@ -322,13 +322,10 @@ describe('ReactDOMServerHooks', () => {
322
itRenders('basic render', async render => {
323
function CapitalizedText(props) {
324
const text = props.text;
325
- const capitalizedText = useMemo(
326
- () => {
327
- yieldValue(`Capitalize '${text}'`);
328
- return text.toUpperCase();
329
- },
330
- [text],
331
- );
325
+ const capitalizedText = useMemo(() => {
326
+ yieldValue(`Capitalize '${text}'`);
327
+ return text.toUpperCase();
328
+ }, [text]);
329
return <Text text={capitalizedText} />;
330
}
331
@@ -360,13 +357,10 @@ describe('ReactDOMServerHooks', () => {
357
async render => {
358
function CapitalizedText(props) {
359
const [text, setText] = useState(props.text);
363
- const capitalizedText = useMemo(
364
- () => {
365
- yieldValue(`Capitalize '${text}'`);
366
- return text.toUpperCase();
367
- },
368
- [text],
369
- );
360
+ const capitalizedText = useMemo(() => {
361
+ yieldValue(`Capitalize '${text}'`);
362
+ return text.toUpperCase();
363
+ }, [text]);
364
365
if (text === 'hello') {
366
setText('hello, world.');
@@ -391,13 +385,10 @@ describe('ReactDOMServerHooks', () => {
385
function CapitalizedText(props) {
386
const [text, setText] = useState(props.text);
387
const [count, setCount] = useState(0);
394
- const capitalizedText = useMemo(
395
- () => {
396
- yieldValue(`Capitalize '${text}'`);
397
- return text.toUpperCase();
398
- },
399
- [text],
400
- );
388
+ const capitalizedText = useMemo(() => {
389
+ yieldValue(`Capitalize '${text}'`);
390
+ return text.toUpperCase();
391
+ }, [text]);
392
393
yieldValue(count);
394
packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.js
+10
-7
@@ -33,13 +33,16 @@ describe('ReactDOMSuspensePlaceholder', () => {
33
container = document.createElement('div');
34
document.body.appendChild(container);
35
36
- TextResource = ReactCache.unstable_createResource(([text, ms = 0]) => {
37
- return new Promise((resolve, reject) =>
38
- setTimeout(() => {
39
- resolve(text);
40
- }, ms),
41
- );
42
- }, ([text, ms]) => text);
36
+ TextResource = ReactCache.unstable_createResource(
37
+ ([text, ms = 0]) => {
38
+ return new Promise((resolve, reject) =>
39
+ setTimeout(() => {
40
+ resolve(text);
41
+ }, ms),
42
+ );
43
+ },
44
+ ([text, ms]) => text,
45
+ );
46
});
47
48
afterEach(() => {
packages/react-dom/src/__tests__/ReactFunctionComponent-test.js
+5
-5
@@ -163,11 +163,11 @@ describe('ReactFunctionComponent', () => {
163
: // It happens because we don't save _owner in production for
164
// function components.
165
'Element ref was specified as a string (me) but no owner was set. This could happen for one of' +
166
- ' the following reasons:\n' +
167
- '1. You may be adding a ref to a function component\n' +
168
- "2. You may be adding a ref to a component that was not created inside a component's render method\n" +
169
- '3. You have multiple copies of React loaded\n' +
170
- 'See https://fb.me/react-refs-must-have-owner for more information.',
166
+ ' the following reasons:\n' +
167
+ '1. You may be adding a ref to a function component\n' +
168
+ "2. You may be adding a ref to a component that was not created inside a component's render method\n" +
169
+ '3. You have multiple copies of React loaded\n' +
170
+ 'See https://fb.me/react-refs-must-have-owner for more information.',
171
);
172
});
173
packages/react-dom/src/__tests__/ReactMount-test.js
+12
-4
@@ -59,7 +59,9 @@ describe('ReactMount', () => {
59
}
60
}
61
62
- expect(() => ReactTestUtils.renderIntoDocument(Component)).toErrorDev(
62
+ expect(() =>
63
+ ReactTestUtils.renderIntoDocument(Component),
64
+ ).toErrorDev(
65
'Functions are not valid as a React child. ' +
66
'This may happen if you return a Component instead of <Component /> from render. ' +
67
'Or maybe you meant to call this function rather than return it.',
@@ -125,7 +127,9 @@ describe('ReactMount', () => {
127
const container = document.createElement('container');
128
container.innerHTML = ReactDOMServer.renderToString(<div />) + ' ';
129
128
- expect(() => ReactDOM.hydrate(<div />, container)).toErrorDev(
130
+ expect(() =>
131
+ ReactDOM.hydrate(<div />, container),
132
+ ).toErrorDev(
133
'Did not expect server HTML to contain the text node " " in <container>.',
134
{withoutStack: true},
135
);
@@ -195,7 +199,9 @@ describe('ReactMount', () => {
199
// Test that blasting away children throws a warning
200
const rootNode = container.firstChild;
201
198
- expect(() => ReactDOM.render(<span />, rootNode)).toErrorDev(
202
+ expect(() =>
203
+ ReactDOM.render(<span />, rootNode),
204
+ ).toErrorDev(
205
'Warning: render(...): Replacing React-rendered children with a new ' +
206
'root component. If you intended to update the children of this node, ' +
207
'you should instead have the existing children update their state and ' +
@@ -223,7 +229,9 @@ describe('ReactMount', () => {
229
// Make sure ReactDOM and ReactDOMOther are different copies
230
expect(ReactDOM).not.toEqual(ReactDOMOther);
231
226
- expect(() => ReactDOMOther.unmountComponentAtNode(container)).toErrorDev(
232
+ expect(() =>
233
+ ReactDOMOther.unmountComponentAtNode(container),
234
+ ).toErrorDev(
235
"Warning: unmountComponentAtNode(): The node you're attempting to unmount " +
236
'was rendered by another copy of React.',
237
{withoutStack: true},
packages/react-dom/src/__tests__/ReactMountDestruction-test.js
+6
-2
@@ -50,7 +50,9 @@ describe('ReactMount', () => {
50
51
// Test that unmounting at a root node gives a helpful warning
52
const rootDiv = mainContainerDiv.firstChild;
53
- expect(() => ReactDOM.unmountComponentAtNode(rootDiv)).toErrorDev(
53
+ expect(() =>
54
+ ReactDOM.unmountComponentAtNode(rootDiv),
55
+ ).toErrorDev(
56
"Warning: unmountComponentAtNode(): The node you're attempting to " +
57
'unmount was rendered by React and is not a top-level container. You ' +
58
'may have accidentally passed in a React root node instead of its ' +
@@ -73,7 +75,9 @@ describe('ReactMount', () => {
75
76
// Test that unmounting at a non-root node gives a different warning
77
const nonRootDiv = mainContainerDiv.firstChild.firstChild;
76
- expect(() => ReactDOM.unmountComponentAtNode(nonRootDiv)).toErrorDev(
78
+ expect(() =>
79
+ ReactDOM.unmountComponentAtNode(nonRootDiv),
80
+ ).toErrorDev(
81
"Warning: unmountComponentAtNode(): The node you're attempting to " +
82
'unmount was rendered by React and is not a top-level container. ' +
83
'Instead, have the parent component update its state and rerender in ' +
packages/react-dom/src/__tests__/ReactMultiChild-test.js
+23
-8
@@ -281,7 +281,16 @@ describe('ReactMultiChild', () => {
281
it('should warn for using maps as children with owner info', () => {
282
class Parent extends React.Component {
283
render() {
284
- return <div>{new Map([['foo', 0], ['bar', 1]])}</div>;
284
+ return (
285
+ <div>
286
+ {
287
+ new Map([
288
+ ['foo', 0],
289
+ ['bar', 1],
290
+ ])
291
+ }
292
+ </div>
293
+ );
294
}
295
}
296
const container = document.createElement('div');
@@ -296,8 +305,8 @@ describe('ReactMultiChild', () => {
305
306
it('should warn for using generators as children', () => {
307
function* Foo() {
299
- yield <h1 key="1">Hello</h1>;
300
- yield <h1 key="2">World</h1>;
308
+ yield (<h1 key="1">Hello</h1>);
309
+ yield (<h1 key="2">World</h1>);
310
}
311
312
const div = document.createElement('div');
@@ -318,8 +327,8 @@ describe('ReactMultiChild', () => {
327
it('should not warn for using generators in legacy iterables', () => {
328
const fooIterable = {
329
'@@iterator': function*() {
321
- yield <h1 key="1">Hello</h1>;
322
- yield <h1 key="2">World</h1>;
330
+ yield (<h1 key="1">Hello</h1>);
331
+ yield (<h1 key="2">World</h1>);
332
},
333
};
334
@@ -338,8 +347,8 @@ describe('ReactMultiChild', () => {
347
it('should not warn for using generators in modern iterables', () => {
348
const fooIterable = {
349
[Symbol.iterator]: function*() {
341
- yield <h1 key="1">Hello</h1>;
342
- yield <h1 key="2">World</h1>;
350
+ yield (<h1 key="1">Hello</h1>);
351
+ yield (<h1 key="2">World</h1>);
352
},
353
};
354
@@ -374,7 +383,13 @@ describe('ReactMultiChild', () => {
383
class Letters extends React.Component {
384
render() {
385
const letters = this.props.letters.split('');
377
- return <div>{letters.map(c => <Letter key={c} char={c} />)}</div>;
386
+ return (
387
+ <div>
388
+ {letters.map(c => (
389
+ <Letter key={c} char={c} />
390
+ ))}
391
+ </div>
392
+ );
393
}
394
}
395
packages/react-dom/src/__tests__/ReactRenderDocument-test.js
+3
-1
@@ -35,7 +35,9 @@ describe('rendering React components at document', () => {
35
36
describe('with old implicit hydration API', () => {
37
function expectDeprecationWarningWithFiber(callback) {
38
- expect(callback).toWarnDev(
38
+ expect(
39
+ callback,
40
+ ).toWarnDev(
41
'render(): Calling ReactDOM.render() to hydrate server-rendered markup ' +
42
'will stop working in React v17. Replace the ReactDOM.render() call ' +
43
'with ReactDOM.hydrate() if you want React to attach to the server HTML.',
packages/react-dom/src/__tests__/ReactServerRendering-test.js
+6
-2
@@ -644,7 +644,9 @@ describe('ReactDOMServer', () => {
644
}
645
646
ReactDOMServer.renderToString(<Foo />);
647
- expect(() => jest.runOnlyPendingTimers()).toErrorDev(
647
+ expect(() =>
648
+ jest.runOnlyPendingTimers(),
649
+ ).toErrorDev(
650
'Warning: setState(...): Can only update a mounting component.' +
651
' This usually means you called setState() outside componentWillMount() on the server.' +
652
' This is a no-op.\n\nPlease check the code for the Foo component.',
@@ -672,7 +674,9 @@ describe('ReactDOMServer', () => {
674
}
675
676
ReactDOMServer.renderToString(<Baz />);
675
- expect(() => jest.runOnlyPendingTimers()).toErrorDev(
677
+ expect(() =>
678
+ jest.runOnlyPendingTimers(),
679
+ ).toErrorDev(
680
'Warning: forceUpdate(...): Can only update a mounting component. ' +
681
'This usually means you called forceUpdate() outside componentWillMount() on the server. ' +
682
'This is a no-op.\n\nPlease check the code for the Baz component.',
packages/react-dom/src/__tests__/ReactTestUtils-test.js
+3
-1
@@ -53,7 +53,9 @@ describe('ReactTestUtils', () => {
53
MockedComponent.prototype.render = jest.fn();
54
55
// Patch it up so it returns its children.
56
- expect(() => ReactTestUtils.mockComponent(MockedComponent)).toWarnDev(
56
+ expect(() =>
57
+ ReactTestUtils.mockComponent(MockedComponent),
58
+ ).toWarnDev(
59
'ReactTestUtils.mockComponent() is deprecated. ' +
60
'Use shallow rendering or jest.mock() instead.\n\n' +
61
'See https://fb.me/test-utils-mock-component for more information.',
packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js
+7
-13
@@ -337,12 +337,9 @@ function runActTests(label, render, unmount, rerender) {
337
await null;
338
setState(x => x + 1);
339
}
340
- React.useEffect(
341
- () => {
342
- ticker();
343
- },
344
- [Math.min(state, 4)],
345
- );
340
+ React.useEffect(() => {
341
+ ticker();
342
+ }, [Math.min(state, 4)]);
343
return state;
344
}
345
@@ -521,13 +518,10 @@ function runActTests(label, render, unmount, rerender) {
518
await null;
519
setState(x => x + 1);
520
}
524
- React.useEffect(
525
- () => {
526
- Scheduler.unstable_yieldValue(state);
527
- ticker();
528
- },
529
- [Math.min(state, 4)],
530
- );
521
+ React.useEffect(() => {
522
+ Scheduler.unstable_yieldValue(state);
523
+ ticker();
524
+ }, [Math.min(state, 4)]);
525
return state;
526
}
527
packages/react-dom/src/__tests__/ReactTestUtilsActUnmockedScheduler-test.js
+4
-7
@@ -147,13 +147,10 @@ it('can handle cascading promises', async () => {
147
await null;
148
setState(x => x + 1);
149
}
150
- React.useEffect(
151
- () => {
152
- yields.push(state);
153
- ticker();
154
- },
155
- [Math.min(state, 4)],
156
- );
150
+ React.useEffect(() => {
151
+ yields.push(state);
152
+ ticker();
153
+ }, [Math.min(state, 4)]);
154
return state;
155
}
156
packages/react-dom/src/__tests__/renderSubtreeIntoContainer-test.js
+5
-5
@@ -312,11 +312,11 @@ describe('renderSubtreeIntoContainer', () => {
312
}).toThrow(
313
__DEV__
314
? '_processChildContext is not available in React 16+. This likely ' +
315
- 'means you have multiple copies of React and are attempting to nest ' +
316
- 'a React 15 tree inside a React 16 tree using ' +
317
- "unstable_renderSubtreeIntoContainer, which isn't supported. Try to " +
318
- 'make sure you have only one copy of React (and ideally, switch to ' +
319
- 'ReactDOM.createPortal).'
315
+ 'means you have multiple copies of React and are attempting to nest ' +
316
+ 'a React 15 tree inside a React 16 tree using ' +
317
+ "unstable_renderSubtreeIntoContainer, which isn't supported. Try to " +
318
+ 'make sure you have only one copy of React (and ideally, switch to ' +
319
+ 'ReactDOM.createPortal).'
320
: "Cannot read property '_processChildContext' of undefined",
321
);
322
});
packages/react-dom/src/client/ReactDOMLegacy.js
+2
-2
@@ -385,9 +385,9 @@ export function unmountComponentAtNode(container: DOMContainer) {
385
'was rendered by React and is not a top-level container. %s',
386
isContainerReactRoot
387
? 'You may have accidentally passed in a React root node instead ' +
388
- 'of its container.'
388
+ 'of its container.'
389
: 'Instead, have the parent component update its state and ' +
390
- 'rerender in order to remove this component.',
390
+ 'rerender in order to remove this component.',
391
);
392
}
393
}
packages/react-dom/src/events/SelectEventPlugin.js
+2
-2
@@ -94,8 +94,8 @@ function getEventTargetDocument(eventTarget) {
94
return eventTarget.window === eventTarget
95
? eventTarget.document
96
: eventTarget.nodeType === DOCUMENT_NODE
97
- ? eventTarget
98
- : eventTarget.ownerDocument;
97
+ ? eventTarget
98
+ : eventTarget.ownerDocument;
99
}
100
101
/**
packages/react-dom/src/events/SyntheticWheelEvent.js
+9
-9
@@ -16,20 +16,20 @@ const SyntheticWheelEvent = SyntheticMouseEvent.extend({
16
return 'deltaX' in event
17
? event.deltaX
18
: // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
19
- 'wheelDeltaX' in event
20
- ? -event.wheelDeltaX
21
- : 0;
19
+ 'wheelDeltaX' in event
20
+ ? -event.wheelDeltaX
21
+ : 0;
22
},
23
deltaY(event) {
24
return 'deltaY' in event
25
? event.deltaY
26
: // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
27
- 'wheelDeltaY' in event
28
- ? -event.wheelDeltaY
29
- : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
30
- 'wheelDelta' in event
31
- ? -event.wheelDelta
32
- : 0;
27
+ 'wheelDeltaY' in event
28
+ ? -event.wheelDeltaY
29
+ : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
30
+ 'wheelDelta' in event
31
+ ? -event.wheelDelta
32
+ : 0;
33
},
34
deltaZ: null,
35
packages/react-dom/src/events/__tests__/SimpleEventPlugin-test.internal.js
+1
-3
@@ -388,9 +388,7 @@ describe('SimpleEventPlugin', function() {
388
class Button extends React.Component {
389
state = {lowPriCount: 0};
390
render() {
391
- const text = `High-pri count: ${
392
- this.props.highPriCount
393
- }, Low-pri count: ${this.state.lowPriCount}`;
391
+ const text = `High-pri count: ${this.props.highPriCount}, Low-pri count: ${this.state.lowPriCount}`;
392
Scheduler.unstable_yieldValue(text);
393
return (
394
<button
packages/react-dom/src/events/__tests__/SyntheticEvent-test.js
+15
-14
@@ -151,18 +151,15 @@ describe('SyntheticEvent', () => {
151
'See https://fb.me/react-event-pooling for more information.';
152
153
// once for each property accessed
154
- expect(() => expect(syntheticEvent.type).toBe(null)).toErrorDev(
155
- getExpectedWarning('type'),
156
- {withoutStack: true},
157
- );
158
- expect(() => expect(syntheticEvent.nativeEvent).toBe(null)).toErrorDev(
159
- getExpectedWarning('nativeEvent'),
160
- {withoutStack: true},
161
- );
162
- expect(() => expect(syntheticEvent.target).toBe(null)).toErrorDev(
163
- getExpectedWarning('target'),
164
- {withoutStack: true},
165
- );
154
+ expect(() =>
155
+ expect(syntheticEvent.type).toBe(null),
156
+ ).toErrorDev(getExpectedWarning('type'), {withoutStack: true});
157
+ expect(() =>
158
+ expect(syntheticEvent.nativeEvent).toBe(null),
159
+ ).toErrorDev(getExpectedWarning('nativeEvent'), {withoutStack: true});
160
+ expect(() =>
161
+ expect(syntheticEvent.target).toBe(null),
162
+ ).toErrorDev(getExpectedWarning('target'), {withoutStack: true});
163
164
expect(expectedCount).toBe(1);
165
});
@@ -211,7 +208,9 @@ describe('SyntheticEvent', () => {
208
event.initEvent('click', true, true);
209
node.dispatchEvent(event);
210
214
- expect(() => syntheticEvent.preventDefault()).toErrorDev(
211
+ expect(() =>
212
+ syntheticEvent.preventDefault(),
213
+ ).toErrorDev(
214
'Warning: This synthetic event is reused for performance reasons. If ' +
215
"you're seeing this, you're accessing the method `preventDefault` on a " +
216
'released/nullified synthetic event. This is a no-op function. If you must ' +
@@ -238,7 +237,9 @@ describe('SyntheticEvent', () => {
237
238
node.dispatchEvent(event);
239
241
- expect(() => syntheticEvent.stopPropagation()).toErrorDev(
240
+ expect(() =>
241
+ syntheticEvent.stopPropagation(),
242
+ ).toErrorDev(
243
'Warning: This synthetic event is reused for performance reasons. If ' +
244
"you're seeing this, you're accessing the method `stopPropagation` on a " +
245
'released/nullified synthetic event. This is a no-op function. If you must ' +
packages/react-interactions/accessibility/src/FocusContain.js
+12
-15
@@ -64,22 +64,19 @@ export default function FocusContain({
64
}
65
},
66
});
67
- useLayoutEffect(
68
- () => {
69
- const scope = scopeRef.current;
70
- if (
71
- scope !== null &&
72
- disabled !== true &&
73
- !scope.containsNode(document.activeElement)
74
- ) {
75
- const fistElem = scope.queryFirstNode(scopeQuery);
76
- if (fistElem !== null) {
77
- fistElem.focus();
78
- }
67
+ useLayoutEffect(() => {
68
+ const scope = scopeRef.current;
69
+ if (
70
+ scope !== null &&
71
+ disabled !== true &&
72
+ !scope.containsNode(document.activeElement)
73
+ ) {
74
+ const fistElem = scope.queryFirstNode(scopeQuery);
75
+ if (fistElem !== null) {
76
+ fistElem.focus();
77
}
80
- },
81
- [disabled],
82
- );
78
+ }
79
+ }, [disabled]);
80
81
return (
82
<FocusContainScope
packages/react-interactions/events/src/dom/Press.js
+3
-3
@@ -95,9 +95,9 @@ function isValidKey(e): boolean {
95
const {tagName, isContentEditable} = (target: any);
96
return (
97
(key === 'Enter' || key === ' ' || key === 'Spacebar') &&
98
- (tagName !== 'INPUT' &&
99
- tagName !== 'TEXTAREA' &&
100
- isContentEditable !== true)
98
+ tagName !== 'INPUT' &&
99
+ tagName !== 'TEXTAREA' &&
100
+ isContentEditable !== true
101
);
102
}
103
packages/react-interactions/events/src/dom/PressLegacy.js
+7
-4
@@ -339,9 +339,9 @@ function isValidKeyboardEvent(nativeEvent: Object): boolean {
339
// "Spacebar" is for IE 11
340
return (
341
(key === 'Enter' || key === ' ' || key === 'Spacebar') &&
342
- (tagName !== 'INPUT' &&
343
- tagName !== 'TEXTAREA' &&
344
- isContentEditable !== true)
342
+ tagName !== 'INPUT' &&
343
+ tagName !== 'TEXTAREA' &&
344
+ isContentEditable !== true
345
);
346
}
347
@@ -480,7 +480,10 @@ function updateIsPressWithinResponderRegion(
480
bottom != null &&
481
x !== null &&
482
y !== null &&
483
- (x >= left && x <= right && y >= top && y <= bottom);
483
+ x >= left &&
484
+ x <= right &&
485
+ y >= top &&
486
+ y <= bottom;
487
}
488
489
// After some investigation work, screen reader virtual
packages/react-native-renderer/src/ReactNativeHostConfig.js
+4
-5
@@ -163,11 +163,10 @@ export function finalizeInitialChildren(
163
164
// Map from child objects to native tags.
165
// Either way we need to pass a copy of the Array to prevent it from being frozen.
166
- const nativeTags = parentInstance._children.map(
167
- child =>
168
- typeof child === 'number'
169
- ? child // Leaf node (eg text)
170
- : child._nativeTag,
166
+ const nativeTags = parentInstance._children.map(child =>
167
+ typeof child === 'number'
168
+ ? child // Leaf node (eg text)
169
+ : child._nativeTag,
170
);
171
172
UIManager.setChildren(
packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js
+13
-7
@@ -280,11 +280,9 @@ describe('ReactFabric', () => {
280
expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
281
ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]);
282
expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledTimes(1);
283
- expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledWith(
284
- expect.any(Object),
285
- 'updateCommand',
286
- [10, 20],
287
- );
283
+ expect(
284
+ nativeFabricUIManager.dispatchCommand,
285
+ ).toHaveBeenCalledWith(expect.any(Object), 'updateCommand', [10, 20]);
286
});
287
});
288
@@ -550,7 +548,11 @@ describe('ReactFabric', () => {
548
render() {
549
const chars = this.props.chars.split('');
550
return (
553
- <View>{chars.map(text => <View key={text} title={text} />)}</View>
551
+ <View>
552
+ {chars.map(text => (
553
+ <View key={text} title={text} />
554
+ ))}
555
+ </View>
556
);
557
}
558
}
@@ -586,7 +588,11 @@ describe('ReactFabric', () => {
588
render() {
589
const chars = this.state.chars.split('');
590
return (
589
- <View>{chars.map(text => <View key={text} title={text} />)}</View>
591
+ <View>
592
+ {chars.map(text => (
593
+ <View key={text} title={text} />
594
+ ))}
595
+ </View>
596
);
597
}
598
}
packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js
+6
-10
@@ -87,11 +87,9 @@ describe('created with ReactFabric called with ReactNative', () => {
87
expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
88
ReactNative.dispatchCommand(ref.current, 'myCommand', [10, 20]);
89
expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledTimes(1);
90
- expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledWith(
91
- expect.any(Object),
92
- 'myCommand',
93
- [10, 20],
94
- );
90
+ expect(
91
+ nativeFabricUIManager.dispatchCommand,
92
+ ).toHaveBeenCalledWith(expect.any(Object), 'myCommand', [10, 20]);
93
expect(UIManager.dispatchViewManagerCommand).not.toBeCalled();
94
});
95
});
@@ -167,11 +165,9 @@ describe('created with ReactNative called with ReactFabric', () => {
165
expect(UIManager.dispatchViewManagerCommand).not.toBeCalled();
166
ReactFabric.dispatchCommand(ref.current, 'myCommand', [10, 20]);
167
expect(UIManager.dispatchViewManagerCommand).toHaveBeenCalledTimes(1);
170
- expect(UIManager.dispatchViewManagerCommand).toHaveBeenCalledWith(
171
- expect.any(Number),
172
- 'myCommand',
173
- [10, 20],
174
- );
168
+ expect(
169
+ UIManager.dispatchViewManagerCommand,
170
+ ).toHaveBeenCalledWith(expect.any(Number), 'myCommand', [10, 20]);
171
172
expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
173
});
packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js
+8
-6
@@ -125,11 +125,9 @@ describe('ReactNative', () => {
125
expect(UIManager.dispatchViewManagerCommand).not.toBeCalled();
126
ReactNative.dispatchCommand(viewRef, 'updateCommand', [10, 20]);
127
expect(UIManager.dispatchViewManagerCommand).toHaveBeenCalledTimes(1);
128
- expect(UIManager.dispatchViewManagerCommand).toHaveBeenCalledWith(
129
- expect.any(Number),
130
- 'updateCommand',
131
- [10, 20],
132
- );
128
+ expect(
129
+ UIManager.dispatchViewManagerCommand,
130
+ ).toHaveBeenCalledWith(expect.any(Number), 'updateCommand', [10, 20]);
131
});
132
});
133
@@ -436,7 +434,11 @@ describe('ReactNative', () => {
434
render() {
435
const chars = this.props.chars.split('');
436
return (
439
- <View>{chars.map(text => <View key={text} title={text} />)}</View>
437
+ <View>
438
+ {chars.map(text => (
439
+ <View key={text} title={text} />
440
+ ))}
441
+ </View>
442
);
443
}
444
}
packages/react-reconciler/src/ReactFiberBeginWork.js
+3
-1
@@ -2384,7 +2384,9 @@ function validateSuspenseListChildren(
2384
if (__DEV__) {
2385
if (
2386
(revealOrder === 'forwards' || revealOrder === 'backwards') &&
2387
- (children !== undefined && children !== null && children !== false)
2387
+ children !== undefined &&
2388
+ children !== null &&
2389
+ children !== false
2390
) {
2391
if (Array.isArray(children)) {
2392
for (let i = 0; i < children.length; i++) {
packages/react-reconciler/src/ReactFiberCommitWork.js
+2
-5
@@ -297,9 +297,7 @@ function commitBeforeMutationLifeCycles(
297
prevState,
298
);
299
if (__DEV__) {
300
- const didWarnSet = ((didWarnAboutUndefinedSnapshotBeforeUpdate: any): Set<
301
- mixed,
302
- >);
300
+ const didWarnSet = ((didWarnAboutUndefinedSnapshotBeforeUpdate: any): Set<mixed>);
301
if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
302
didWarnSet.add(finishedWork.type);
303
console.error(
@@ -940,8 +938,7 @@ function commitContainer(finishedWork: Fiber) {
938
const portalOrRoot: {
939
containerInfo: Container,
940
pendingChildren: ChildSet,
943
- } =
944
- finishedWork.stateNode;
941
+ } = finishedWork.stateNode;
942
const {containerInfo, pendingChildren} = portalOrRoot;
943
replaceContainerChildren(containerInfo, pendingChildren);
944
return;
packages/react-reconciler/src/ReactFiberCompleteWork.js
+2
-4
@@ -435,8 +435,7 @@ if (supportsMutation) {
435
const portalOrRoot: {
436
containerInfo: Container,
437
pendingChildren: ChildSet,
438
- } =
439
- workInProgress.stateNode;
438
+ } = workInProgress.stateNode;
439
const childrenUnchanged = workInProgress.firstEffect === null;
440
if (childrenUnchanged) {
441
// No changes, just reuse the existing instance.
@@ -1201,8 +1200,7 @@ function completeWork(
1200
let fundamentalInstance: ReactFundamentalComponentInstance<
1201
any,
1202
any,
1204
- > | null =
1205
- workInProgress.stateNode;
1203
+ > | null = workInProgress.stateNode;
1204
1205
if (fundamentalInstance === null) {
1206
const getInitialState = fundamentalImpl.getInitialState;
packages/react-reconciler/src/ReactFiberHooks.js
+18
-24
@@ -1141,18 +1141,15 @@ function mountDeferredValue<T>(
1141
config: TimeoutConfig | void | null,
1142
): T {
1143
const [prevValue, setValue] = mountState(value);
1144
- mountEffect(
1145
- () => {
1146
- const previousConfig = ReactCurrentBatchConfig.suspense;
1147
- ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1148
- try {
1149
- setValue(value);
1150
- } finally {
1151
- ReactCurrentBatchConfig.suspense = previousConfig;
1152
- }
1153
- },
1154
- [value, config],
1155
- );
1144
+ mountEffect(() => {
1145
+ const previousConfig = ReactCurrentBatchConfig.suspense;
1146
+ ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1147
+ try {
1148
+ setValue(value);
1149
+ } finally {
1150
+ ReactCurrentBatchConfig.suspense = previousConfig;
1151
+ }
1152
+ }, [value, config]);
1153
return prevValue;
1154
}
1155
@@ -1161,18 +1158,15 @@ function updateDeferredValue<T>(
1158
config: TimeoutConfig | void | null,
1159
): T {
1160
const [prevValue, setValue] = updateState(value);
1164
- updateEffect(
1165
- () => {
1166
- const previousConfig = ReactCurrentBatchConfig.suspense;
1167
- ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1168
- try {
1169
- setValue(value);
1170
- } finally {
1171
- ReactCurrentBatchConfig.suspense = previousConfig;
1172
- }
1173
- },
1174
- [value, config],
1175
- );
1161
+ updateEffect(() => {
1162
+ const previousConfig = ReactCurrentBatchConfig.suspense;
1163
+ ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1164
+ try {
1165
+ setValue(value);
1166
+ } finally {
1167
+ ReactCurrentBatchConfig.suspense = previousConfig;
1168
+ }
1169
+ }, [value, config]);
1170
return prevValue;
1171
}
1172
packages/react-reconciler/src/ReactFiberRoot.js
+2
-2
@@ -163,8 +163,8 @@ export function isRootSuspendedAtTime(
163
const lastSuspendedTime = root.lastSuspendedTime;
164
return (
165
firstSuspendedTime !== NoWork &&
166
- (firstSuspendedTime >= expirationTime &&
167
- lastSuspendedTime <= expirationTime)
166
+ firstSuspendedTime >= expirationTime &&
167
+ lastSuspendedTime <= expirationTime
168
);
169
}
170
packages/react-reconciler/src/ReactFiberWorkLoop.js
+10
-10
@@ -2466,16 +2466,16 @@ function jnd(timeElapsed: number) {
2466
return timeElapsed < 120
2467
? 120
2468
: timeElapsed < 480
2469
- ? 480
2470
- : timeElapsed < 1080
2471
- ? 1080
2472
- : timeElapsed < 1920
2473
- ? 1920
2474
- : timeElapsed < 3000
2475
- ? 3000
2476
- : timeElapsed < 4320
2477
- ? 4320
2478
- : ceil(timeElapsed / 1960) * 1960;
2469
+ ? 480
2470
+ : timeElapsed < 1080
2471
+ ? 1080
2472
+ : timeElapsed < 1920
2473
+ ? 1920
2474
+ : timeElapsed < 3000
2475
+ ? 3000
2476
+ : timeElapsed < 4320
2477
+ ? 4320
2478
+ : ceil(timeElapsed / 1960) * 1960;
2479
}
2480
2481
function computeMsUntilSuspenseLoadingDelay(
packages/react-reconciler/src/__tests__/ReactBatchedMode-test.internal.js
+11
-8
@@ -18,14 +18,17 @@ describe('ReactBlockingMode', () => {
18
ReactCache = require('react-cache');
19
Suspense = React.Suspense;
20
21
- TextResource = ReactCache.unstable_createResource(([text, ms = 0]) => {
22
- return new Promise((resolve, reject) =>
23
- setTimeout(() => {
24
- Scheduler.unstable_yieldValue(`Promise resolved [${text}]`);
25
- resolve(text);
26
- }, ms),
27
- );
28
- }, ([text, ms]) => text);
21
+ TextResource = ReactCache.unstable_createResource(
22
+ ([text, ms = 0]) => {
23
+ return new Promise((resolve, reject) =>
24
+ setTimeout(() => {
25
+ Scheduler.unstable_yieldValue(`Promise resolved [${text}]`);
26
+ resolve(text);
27
+ }, ms),
28
+ );
29
+ },
30
+ ([text, ms]) => text,
31
+ );
32
});
33
34
function Text(props) {
packages/react-reconciler/src/__tests__/ReactFragment-test.js
+2
-2
@@ -23,8 +23,8 @@ describe('ReactFragment', () => {
23
});
24
25
function div(...children) {
26
- children = children.map(
27
- c => (typeof c === 'string' ? {text: c, hidden: false} : c),
26
+ children = children.map(c =>
27
+ typeof c === 'string' ? {text: c, hidden: false} : c,
28
);
29
return {type: 'div', children, prop: undefined, hidden: false};
30
}
packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
+11
-5
@@ -625,10 +625,13 @@ describe('ReactHooks', () => {
625
it('warns if switching from dependencies to no dependencies', () => {
626
const {useMemo} = React;
627
function App({text, hasDeps}) {
628
- const resolvedText = useMemo(() => {
629
- Scheduler.unstable_yieldValue('Compute');
630
- return text.toUpperCase();
631
- }, hasDeps ? null : [text]);
628
+ const resolvedText = useMemo(
629
+ () => {
630
+ Scheduler.unstable_yieldValue('Compute');
631
+ return text.toUpperCase();
632
+ },
633
+ hasDeps ? null : [text],
634
+ );
635
return resolvedText;
636
}
637
@@ -1183,7 +1186,10 @@ describe('ReactHooks', () => {
1186
React.useLayoutEffect(() => {});
1187
React.useCallback(() => {});
1188
React.useRef();
1186
- React.useImperativeHandle(() => {}, () => {});
1189
+ React.useImperativeHandle(
1190
+ () => {},
1191
+ () => {},
1192
+ );
1193
if (__DEV__) {
1194
React.useDebugValue();
1195
}
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js
+49
-67
@@ -63,14 +63,17 @@ describe('ReactHooksWithNoopRenderer', () => {
63
Suspense = React.Suspense;
64
act = ReactNoop.act;
65
66
- TextResource = ReactCache.unstable_createResource(([text, ms = 0]) => {
67
- return new Promise((resolve, reject) =>
68
- setTimeout(() => {
69
- Scheduler.unstable_yieldValue(`Promise resolved [${text}]`);
70
- resolve(text);
71
- }, ms),
72
- );
73
- }, ([text, ms]) => text);
66
+ TextResource = ReactCache.unstable_createResource(
67
+ ([text, ms = 0]) => {
68
+ return new Promise((resolve, reject) =>
69
+ setTimeout(() => {
70
+ Scheduler.unstable_yieldValue(`Promise resolved [${text}]`);
71
+ resolve(text);
72
+ }, ms),
73
+ );
74
+ },
75
+ ([text, ms]) => text,
76
+ );
77
});
78
79
function span(prop) {
@@ -846,13 +849,10 @@ describe('ReactHooksWithNoopRenderer', () => {
849
it('updates have async priority', () => {
850
function Counter(props) {
851
const [count, updateCount] = useState('(empty)');
849
- useEffect(
850
- () => {
851
- Scheduler.unstable_yieldValue(`Schedule update [${props.count}]`);
852
- updateCount(props.count);
853
- },
854
- [props.count],
855
- );
852
+ useEffect(() => {
853
+ Scheduler.unstable_yieldValue(`Schedule update [${props.count}]`);
854
+ updateCount(props.count);
855
+ }, [props.count]);
856
return <Text text={'Count: ' + count} />;
857
}
858
act(() => {
@@ -884,13 +884,10 @@ describe('ReactHooksWithNoopRenderer', () => {
884
it('updates have async priority even if effects are flushed early', () => {
885
function Counter(props) {
886
const [count, updateCount] = useState('(empty)');
887
- useEffect(
888
- () => {
889
- Scheduler.unstable_yieldValue(`Schedule update [${props.count}]`);
890
- updateCount(props.count);
891
- },
892
- [props.count],
893
- );
887
+ useEffect(() => {
888
+ Scheduler.unstable_yieldValue(`Schedule update [${props.count}]`);
889
+ updateCount(props.count);
890
+ }, [props.count]);
891
return <Text text={'Count: ' + count} />;
892
}
893
act(() => {
@@ -1038,19 +1035,16 @@ describe('ReactHooksWithNoopRenderer', () => {
1035
() => {
1036
function Counter(props) {
1037
const [count, updateCount] = useState('(empty)');
1041
- useEffect(
1042
- () => {
1043
- // Update multiple times. These should all be batched together in
1044
- // a single render.
1045
- updateCount(props.count);
1046
- updateCount(props.count);
1047
- updateCount(props.count);
1048
- updateCount(props.count);
1049
- updateCount(props.count);
1050
- updateCount(props.count);
1051
- },
1052
- [props.count],
1053
- );
1038
+ useEffect(() => {
1039
+ // Update multiple times. These should all be batched together in
1040
+ // a single render.
1041
+ updateCount(props.count);
1042
+ updateCount(props.count);
1043
+ updateCount(props.count);
1044
+ updateCount(props.count);
1045
+ updateCount(props.count);
1046
+ updateCount(props.count);
1047
+ }, [props.count]);
1048
return <Text text={'Count: ' + count} />;
1049
}
1050
act(() => {
@@ -1071,15 +1065,12 @@ describe('ReactHooksWithNoopRenderer', () => {
1065
it('flushSync is not allowed', () => {
1066
function Counter(props) {
1067
const [count, updateCount] = useState('(empty)');
1074
- useEffect(
1075
- () => {
1076
- Scheduler.unstable_yieldValue(`Schedule update [${props.count}]`);
1077
- ReactNoop.flushSync(() => {
1078
- updateCount(props.count);
1079
- });
1080
- },
1081
- [props.count],
1082
- );
1068
+ useEffect(() => {
1069
+ Scheduler.unstable_yieldValue(`Schedule update [${props.count}]`);
1070
+ ReactNoop.flushSync(() => {
1071
+ updateCount(props.count);
1072
+ });
1073
+ }, [props.count]);
1074
return <Text text={'Count: ' + count} />;
1075
}
1076
act(() => {
@@ -1227,15 +1218,12 @@ describe('ReactHooksWithNoopRenderer', () => {
1218
it('skips effect if inputs have not changed', () => {
1219
function Counter(props) {
1220
const text = `${props.label}: ${props.count}`;
1230
- useEffect(
1231
- () => {
1232
- Scheduler.unstable_yieldValue(`Did create [${text}]`);
1233
- return () => {
1234
- Scheduler.unstable_yieldValue(`Did destroy [${text}]`);
1235
- };
1236
- },
1237
- [props.label, props.count],
1238
- );
1221
+ useEffect(() => {
1222
+ Scheduler.unstable_yieldValue(`Did create [${text}]`);
1223
+ return () => {
1224
+ Scheduler.unstable_yieldValue(`Did destroy [${text}]`);
1225
+ };
1226
+ }, [props.label, props.count]);
1227
return <Text text={text} />;
1228
}
1229
act(() => {
@@ -1699,13 +1687,10 @@ describe('ReactHooksWithNoopRenderer', () => {
1687
it('memoizes value by comparing to previous inputs', () => {
1688
function CapitalizedText(props) {
1689
const text = props.text;
1702
- const capitalizedText = useMemo(
1703
- () => {
1704
- Scheduler.unstable_yieldValue(`Capitalize '${text}'`);
1705
- return text.toUpperCase();
1706
- },
1707
- [text],
1708
- );
1690
+ const capitalizedText = useMemo(() => {
1691
+ Scheduler.unstable_yieldValue(`Capitalize '${text}'`);
1692
+ return text.toUpperCase();
1693
+ }, [text]);
1694
return <Text text={capitalizedText} />;
1695
}
1696
@@ -2364,13 +2349,10 @@ describe('ReactHooksWithNoopRenderer', () => {
2349
Scheduler.unstable_yieldValue('Reducer: ' + count);
2350
return count;
2351
}, -1);
2367
- useEffect(
2368
- () => {
2369
- Scheduler.unstable_yieldValue('Effect: ' + count);
2370
- dispatch();
2371
- },
2372
- [count],
2373
- );
2352
+ useEffect(() => {
2353
+ Scheduler.unstable_yieldValue('Effect: ' + count);
2354
+ dispatch();
2355
+ }, [count]);
2356
Scheduler.unstable_yieldValue('Render: ' + state);
2357
return count;
2358
}
packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js
+27
-9
@@ -2000,7 +2000,9 @@ describe('ReactIncremental', () => {
2000
}
2001
2002
ReactNoop.render(<Recurse />);
2003
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2003
+ expect(() =>
2004
+ expect(Scheduler).toFlushWithoutYielding(),
2005
+ ).toErrorDev(
2006
'Legacy context API has been detected within a strict-mode tree.\n\n' +
2007
'The old API will be supported in all 16.x releases, but applications ' +
2008
'using it should migrate to the new version.\n\n' +
@@ -2194,7 +2196,9 @@ describe('ReactIncremental', () => {
2196
</IndirectionFn>
2197
</Intl>,
2198
);
2197
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2199
+ expect(() =>
2200
+ expect(Scheduler).toFlushWithoutYielding(),
2201
+ ).toErrorDev(
2202
'Legacy context API has been detected within a strict-mode tree.\n\n' +
2203
'The old API will be supported in all 16.x releases, but applications ' +
2204
'using it should migrate to the new version.\n\n' +
@@ -2288,7 +2292,9 @@ describe('ReactIncremental', () => {
2292
</IndirectionFn>
2293
</Stateful>,
2294
);
2291
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2295
+ expect(() =>
2296
+ expect(Scheduler).toFlushWithoutYielding(),
2297
+ ).toErrorDev(
2298
'Legacy context API has been detected within a strict-mode tree.\n\n' +
2299
'The old API will be supported in all 16.x releases, but applications ' +
2300
'using it should migrate to the new version.\n\n' +
@@ -2359,7 +2365,9 @@ describe('ReactIncremental', () => {
2365
2366
// Init
2367
ReactNoop.render(<Root />);
2362
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2368
+ expect(() =>
2369
+ expect(Scheduler).toFlushWithoutYielding(),
2370
+ ).toErrorDev(
2371
'Legacy context API has been detected within a strict-mode tree.\n\n' +
2372
'The old API will be supported in all 16.x releases, but applications ' +
2373
'using it should migrate to the new version.\n\n' +
@@ -2411,7 +2419,9 @@ describe('ReactIncremental', () => {
2419
2420
// Init
2421
ReactNoop.render(<Root />);
2414
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2422
+ expect(() =>
2423
+ expect(Scheduler).toFlushWithoutYielding(),
2424
+ ).toErrorDev(
2425
'Legacy context API has been detected within a strict-mode tree.\n\n' +
2426
'The old API will be supported in all 16.x releases, but applications ' +
2427
'using it should migrate to the new version.\n\n' +
@@ -2612,7 +2622,9 @@ describe('ReactIncremental', () => {
2622
</TopContextProvider>,
2623
);
2624
2615
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2625
+ expect(() =>
2626
+ expect(Scheduler).toFlushWithoutYielding(),
2627
+ ).toErrorDev(
2628
'Legacy context API has been detected within a strict-mode tree.\n\n' +
2629
'The old API will be supported in all 16.x releases, but applications ' +
2630
'using it should migrate to the new version.\n\n' +
@@ -2676,7 +2688,9 @@ describe('ReactIncremental', () => {
2688
</TopContextProvider>,
2689
);
2690
2679
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2691
+ expect(() =>
2692
+ expect(Scheduler).toFlushWithoutYielding(),
2693
+ ).toErrorDev(
2694
'Legacy context API has been detected within a strict-mode tree.\n\n' +
2695
'The old API will be supported in all 16.x releases, but applications ' +
2696
'using it should migrate to the new version.\n\n' +
@@ -2749,7 +2763,9 @@ describe('ReactIncremental', () => {
2763
</TopContextProvider>,
2764
);
2765
2752
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2766
+ expect(() =>
2767
+ expect(Scheduler).toFlushWithoutYielding(),
2768
+ ).toErrorDev(
2769
'Legacy context API has been detected within a strict-mode tree.\n\n' +
2770
'The old API will be supported in all 16.x releases, but applications ' +
2771
'using it should migrate to the new version.\n\n' +
@@ -2832,7 +2848,9 @@ describe('ReactIncremental', () => {
2848
</TopContextProvider>,
2849
);
2850
2835
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2851
+ expect(() =>
2852
+ expect(Scheduler).toFlushWithoutYielding(),
2853
+ ).toErrorDev(
2854
'Legacy context API has been detected within a strict-mode tree.\n\n' +
2855
'The old API will be supported in all 16.x releases, but applications ' +
2856
'using it should migrate to the new version.\n\n' +
packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+6
-2
@@ -1148,7 +1148,9 @@ describe('ReactIncrementalErrorHandling', () => {
1148
<Connector />
1149
</Provider>,
1150
);
1151
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
1151
+ expect(() =>
1152
+ expect(Scheduler).toFlushWithoutYielding(),
1153
+ ).toErrorDev(
1154
'Legacy context API has been detected within a strict-mode tree.\n\n' +
1155
'The old API will be supported in all 16.x releases, but ' +
1156
'applications using it should migrate to the new version.\n\n' +
@@ -1252,7 +1254,9 @@ describe('ReactIncrementalErrorHandling', () => {
1254
1255
it('recovers from uncaught reconciler errors', () => {
1256
const InvalidType = undefined;
1255
- expect(() => ReactNoop.render(<InvalidType />)).toErrorDev(
1257
+ expect(() =>
1258
+ ReactNoop.render(<InvalidType />),
1259
+ ).toErrorDev(
1260
'Warning: React.createElement: type is invalid -- expected a string',
1261
{withoutStack: true},
1262
);
packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.internal.js
+5
-3
@@ -26,8 +26,8 @@ describe('ReactIncrementalReflection', () => {
26
});
27
28
function div(...children) {
29
- children = children.map(
30
- c => (typeof c === 'string' ? {text: c, hidden: false} : c),
29
+ children = children.map(c =>
30
+ typeof c === 'string' ? {text: c, hidden: false} : c,
31
);
32
return {type: 'div', children, prop: undefined, hidden: false};
33
}
@@ -114,7 +114,9 @@ describe('ReactIncrementalReflection', () => {
114
}
115
116
ReactNoop.render(<Foo mount={true} />);
117
- expect(() => expect(Scheduler).toFlushAndYield(['Component'])).toErrorDev(
117
+ expect(() =>
118
+ expect(Scheduler).toFlushAndYield(['Component']),
119
+ ).toErrorDev(
120
'Using UNSAFE_componentWillMount in strict mode is not recommended',
121
{withoutStack: true},
122
);
packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.internal.js
+3
-6
@@ -90,12 +90,9 @@ describe('ReactIncrementalScheduling', () => {
90
it('works on deferred roots in the order they were scheduled', () => {
91
const {useEffect} = React;
92
function Text({text}) {
93
- useEffect(
94
- () => {
95
- Scheduler.unstable_yieldValue(text);
96
- },
97
- [text],
98
- );
93
+ useEffect(() => {
94
+ Scheduler.unstable_yieldValue(text);
95
+ }, [text]);
96
return text;
97
}
98
packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.internal.js
+4
-4
@@ -26,8 +26,8 @@ describe('ReactIncrementalSideEffects', () => {
26
});
27
28
function div(...children) {
29
- children = children.map(
30
- c => (typeof c === 'string' ? {text: c, hidden: false} : c),
29
+ children = children.map(c =>
30
+ typeof c === 'string' ? {text: c, hidden: false} : c,
31
);
32
return {type: 'div', children, prop: undefined, hidden: false};
33
}
@@ -75,8 +75,8 @@ describe('ReactIncrementalSideEffects', () => {
75
{props.text === 'World'
76
? [<Bar key="a" text={props.text} />, <div key="b" />]
77
: props.text === 'Hi'
78
- ? [<div key="b" />, <Bar key="a" text={props.text} />]
79
- : null}
78
+ ? [<div key="b" />, <Bar key="a" text={props.text} />]
79
+ : null}
80
<span prop="test" />
81
</div>
82
);
packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.internal.js
+16
-17
@@ -345,7 +345,9 @@ describe('ReactIncrementalUpdates', () => {
345
}
346
}
347
ReactNoop.render(<Foo />);
348
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
348
+ expect(() =>
349
+ expect(Scheduler).toFlushWithoutYielding(),
350
+ ).toErrorDev(
351
'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended',
352
{withoutStack: true},
353
);
@@ -663,22 +665,19 @@ describe('ReactIncrementalUpdates', () => {
665
setLog(prevLog => prevLog + msg);
666
};
667
666
- useLayoutEffect(
667
- () => {
668
- Scheduler.unstable_yieldValue('Committed: ' + log);
669
- if (log === 'B') {
670
- // Right after B commits, schedule additional updates.
671
- Scheduler.unstable_runWithPriority(
672
- Scheduler.unstable_UserBlockingPriority,
673
- () => {
674
- pushToLog('C');
675
- },
676
- );
677
- setLog(prevLog => prevLog + 'D');
678
- }
679
- },
680
- [log],
681
- );
668
+ useLayoutEffect(() => {
669
+ Scheduler.unstable_yieldValue('Committed: ' + log);
670
+ if (log === 'B') {
671
+ // Right after B commits, schedule additional updates.
672
+ Scheduler.unstable_runWithPriority(
673
+ Scheduler.unstable_UserBlockingPriority,
674
+ () => {
675
+ pushToLog('C');
676
+ },
677
+ );
678
+ setLog(prevLog => prevLog + 'D');
679
+ }
680
+ }, [log]);
681
682
return log;
683
}
packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
+1
-3
@@ -466,9 +466,7 @@ describe('ReactLazy', () => {
466
467
UNSAFE_componentWillReceiveProps(nextProps) {
468
Scheduler.unstable_yieldValue(
469
- `UNSAFE_componentWillReceiveProps: ${this.props.text} -> ${
470
- nextProps.text
471
- }`,
469
+ `UNSAFE_componentWillReceiveProps: ${this.props.text} -> ${nextProps.text}`,
470
);
471
}
472
packages/react-reconciler/src/__tests__/ReactMemo-test.internal.js
+6
-2
@@ -311,7 +311,9 @@ describe('memo', () => {
311
});
312
313
it('warns if the first argument is undefined', () => {
314
- expect(() => memo()).toErrorDev(
314
+ expect(() =>
315
+ memo(),
316
+ ).toErrorDev(
317
'memo: The first argument must be a component. Instead ' +
318
'received: undefined',
319
{withoutStack: true},
@@ -319,7 +321,9 @@ describe('memo', () => {
321
});
322
323
it('warns if the first argument is null', () => {
322
- expect(() => memo(null)).toErrorDev(
324
+ expect(() =>
325
+ memo(null),
326
+ ).toErrorDev(
327
'memo: The first argument must be a component. Instead ' +
328
'received: null',
329
{withoutStack: true},
packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js
+4
-6
@@ -59,7 +59,7 @@ describe('ReactNewContext', () => {
59
}).toErrorDev(
60
observedBits !== undefined
61
? 'useContext() second argument is reserved for future use in React. ' +
62
- `Passing it is not supported. You passed: ${observedBits}.`
62
+ `Passing it is not supported. You passed: ${observedBits}.`
63
: [],
64
);
65
const render = props.children;
@@ -75,7 +75,7 @@ describe('ReactNewContext', () => {
75
}).toErrorDev(
76
observedBits !== undefined
77
? 'useContext() second argument is reserved for future use in React. ' +
78
- `Passing it is not supported. You passed: ${observedBits}.`
78
+ `Passing it is not supported. You passed: ${observedBits}.`
79
: [],
80
);
81
const render = props.children;
@@ -91,7 +91,7 @@ describe('ReactNewContext', () => {
91
}).toErrorDev(
92
observedBits !== undefined
93
? 'useContext() second argument is reserved for future use in React. ' +
94
- `Passing it is not supported. You passed: ${observedBits}.`
94
+ `Passing it is not supported. You passed: ${observedBits}.`
95
: [],
96
);
97
const render = props.children;
@@ -811,9 +811,7 @@ describe('ReactNewContext', () => {
811
Scheduler.unstable_yieldValue('Child');
812
return (
813
<span
814
- prop={`Context: ${this.props.context}, Step: ${
815
- this.state.step
816
- }`}
814
+ prop={`Context: ${this.props.context}, Step: ${this.state.step}`}
815
/>
816
);
817
}
packages/react-reconciler/src/__tests__/ReactPersistent-test.js
+2
-2
@@ -39,8 +39,8 @@ describe('ReactPersistent', () => {
39
}
40
41
function div(...children) {
42
- children = children.map(
43
- c => (typeof c === 'string' ? {text: c, hidden: false} : c),
42
+ children = children.map(c =>
43
+ typeof c === 'string' ? {text: c, hidden: false} : c,
44
);
45
return {type: 'div', children, prop: undefined, hidden: false};
46
}
packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.internal.js
+1
-2
@@ -403,8 +403,7 @@ describe('ReactSchedulerIntegration', () => {
403
expect(Scheduler).toHaveYielded(['Hidden: B']);
404
expect(root).toMatchRenderedOutput(
405
<>
406
- Visible: B
407
- <div hidden={true}>Hidden: B</div>
406
+ Visible: B<div hidden={true}>Hidden: B</div>
407
</>,
408
);
409
});
packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js
+48
-44
@@ -28,46 +28,53 @@ describe('ReactSuspense', () => {
28
29
Suspense = React.Suspense;
30
31
- TextResource = ReactCache.unstable_createResource(([text, ms = 0]) => {
32
- let listeners = null;
33
- let status = 'pending';
34
- let value = null;
35
- return {
36
- then(resolve, reject) {
37
- switch (status) {
38
- case 'pending': {
39
- if (listeners === null) {
40
- listeners = [{resolve, reject}];
41
- setTimeout(() => {
42
- if (textResourceShouldFail) {
43
- Scheduler.unstable_yieldValue(`Promise rejected [${text}]`);
44
- status = 'rejected';
45
- value = new Error('Failed to load: ' + text);
46
- listeners.forEach(listener => listener.reject(value));
47
- } else {
48
- Scheduler.unstable_yieldValue(`Promise resolved [${text}]`);
49
- status = 'resolved';
50
- value = text;
51
- listeners.forEach(listener => listener.resolve(value));
52
- }
53
- }, ms);
54
- } else {
55
- listeners.push({resolve, reject});
31
+ TextResource = ReactCache.unstable_createResource(
32
+ ([text, ms = 0]) => {
33
+ let listeners = null;
34
+ let status = 'pending';
35
+ let value = null;
36
+ return {
37
+ then(resolve, reject) {
38
+ switch (status) {
39
+ case 'pending': {
40
+ if (listeners === null) {
41
+ listeners = [{resolve, reject}];
42
+ setTimeout(() => {
43
+ if (textResourceShouldFail) {
44
+ Scheduler.unstable_yieldValue(
45
+ `Promise rejected [${text}]`,
46
+ );
47
+ status = 'rejected';
48
+ value = new Error('Failed to load: ' + text);
49
+ listeners.forEach(listener => listener.reject(value));
50
+ } else {
51
+ Scheduler.unstable_yieldValue(
52
+ `Promise resolved [${text}]`,
53
+ );
54
+ status = 'resolved';
55
+ value = text;
56
+ listeners.forEach(listener => listener.resolve(value));
57
+ }
58
+ }, ms);
59
+ } else {
60
+ listeners.push({resolve, reject});
61
+ }
62
+ break;
63
+ }
64
+ case 'resolved': {
65
+ resolve(value);
66
+ break;
67
+ }
68
+ case 'rejected': {
69
+ reject(value);
70
+ break;
71
}
57
- break;
58
- }
59
- case 'resolved': {
60
- resolve(value);
61
- break;
62
- }
63
- case 'rejected': {
64
- reject(value);
65
- break;
72
}
67
- }
68
- },
69
- };
70
- }, ([text, ms]) => text);
73
+ },
74
+ };
75
+ },
76
+ ([text, ms]) => text,
77
+ );
78
textResourceShouldFail = false;
79
});
80
@@ -884,12 +891,9 @@ describe('ReactSuspense', () => {
891
function AsyncTextWithEffect(props) {
892
const text = props.text;
893
887
- useLayoutEffect(
888
- () => {
889
- Scheduler.unstable_yieldValue('Did commit: ' + text);
890
- },
891
- [text],
892
- );
894
+ useLayoutEffect(() => {
895
+ Scheduler.unstable_yieldValue('Did commit: ' + text);
896
+ }, [text]);
897
898
try {
899
TextResource.read([props.text, props.ms]);
packages/react-reconciler/src/__tests__/ReactSuspenseFuzz-test.internal.js
+44
-50
@@ -46,32 +46,29 @@ describe('ReactSuspenseFuzz', () => {
46
function Container({children, updates}) {
47
const [step, setStep] = useState(0);
48
49
- useLayoutEffect(
50
- () => {
51
- if (updates !== undefined) {
52
- const cleanUps = new Set();
53
- updates.forEach(({remountAfter}, i) => {
54
- const task = {
55
- label: `Remount children after ${remountAfter}ms`,
56
- };
57
- const timeoutID = setTimeout(() => {
58
- pendingTasks.delete(task);
59
- Scheduler.unstable_yieldValue(task.label);
60
- setStep(i + 1);
61
- }, remountAfter);
62
- pendingTasks.add(task);
63
- cleanUps.add(() => {
64
- pendingTasks.delete(task);
65
- clearTimeout(timeoutID);
66
- });
67
- });
68
- return () => {
69
- cleanUps.forEach(cleanUp => cleanUp());
49
+ useLayoutEffect(() => {
50
+ if (updates !== undefined) {
51
+ const cleanUps = new Set();
52
+ updates.forEach(({remountAfter}, i) => {
53
+ const task = {
54
+ label: `Remount children after ${remountAfter}ms`,
55
};
71
- }
72
- },
73
- [updates],
74
- );
56
+ const timeoutID = setTimeout(() => {
57
+ pendingTasks.delete(task);
58
+ Scheduler.unstable_yieldValue(task.label);
59
+ setStep(i + 1);
60
+ }, remountAfter);
61
+ pendingTasks.add(task);
62
+ cleanUps.add(() => {
63
+ pendingTasks.delete(task);
64
+ clearTimeout(timeoutID);
65
+ });
66
+ });
67
+ return () => {
68
+ cleanUps.forEach(cleanUp => cleanUp());
69
+ };
70
+ }
71
+ }, [updates]);
72
73
return <React.Fragment key={step}>{children}</React.Fragment>;
74
}
@@ -79,32 +76,29 @@ describe('ReactSuspenseFuzz', () => {
76
function Text({text, initialDelay = 0, updates}) {
77
const [[step, delay], setStep] = useState([0, initialDelay]);
78
82
- useLayoutEffect(
83
- () => {
84
- if (updates !== undefined) {
85
- const cleanUps = new Set();
86
- updates.forEach(({beginAfter, suspendFor}, i) => {
87
- const task = {
88
- label: `Update ${beginAfter}ms after mount and suspend for ${suspendFor}ms [${text}]`,
89
- };
90
- const timeoutID = setTimeout(() => {
91
- pendingTasks.delete(task);
92
- Scheduler.unstable_yieldValue(task.label);
93
- setStep([i + 1, suspendFor]);
94
- }, beginAfter);
95
- pendingTasks.add(task);
96
- cleanUps.add(() => {
97
- pendingTasks.delete(task);
98
- clearTimeout(timeoutID);
99
- });
100
- });
101
- return () => {
102
- cleanUps.forEach(cleanUp => cleanUp());
79
+ useLayoutEffect(() => {
80
+ if (updates !== undefined) {
81
+ const cleanUps = new Set();
82
+ updates.forEach(({beginAfter, suspendFor}, i) => {
83
+ const task = {
84
+ label: `Update ${beginAfter}ms after mount and suspend for ${suspendFor}ms [${text}]`,
85
};
104
- }
105
- },
106
- [updates],
107
- );
86
+ const timeoutID = setTimeout(() => {
87
+ pendingTasks.delete(task);
88
+ Scheduler.unstable_yieldValue(task.label);
89
+ setStep([i + 1, suspendFor]);
90
+ }, beginAfter);
91
+ pendingTasks.add(task);
92
+ cleanUps.add(() => {
93
+ pendingTasks.delete(task);
94
+ clearTimeout(timeoutID);
95
+ });
96
+ });
97
+ return () => {
98
+ cleanUps.forEach(cleanUp => cleanUp());
99
+ };
100
+ }
101
+ }, [updates]);
102
103
const fullText = `${text}:${step}`;
104
packages/react-reconciler/src/__tests__/ReactSuspenseList-test.internal.js
+81
-10
@@ -925,7 +925,14 @@ describe('ReactSuspenseList', () => {
925
await B.resolve();
926
await D.resolve();
927
928
- ReactNoop.render(<Foo items={[['B', B], ['D', D]]} />);
928
+ ReactNoop.render(
929
+ <Foo
930
+ items={[
931
+ ['B', B],
932
+ ['D', D],
933
+ ]}
934
+ />,
935
+ );
936
937
expect(Scheduler).toFlushAndYield(['B', 'D']);
938
@@ -939,7 +946,14 @@ describe('ReactSuspenseList', () => {
946
// Insert items in the beginning, middle and end.
947
ReactNoop.render(
948
<Foo
942
- items={[['A', A], ['B', B], ['C', C], ['D', D], ['E', E], ['F', F]]}
949
+ items={[
950
+ ['A', A],
951
+ ['B', B],
952
+ ['C', C],
953
+ ['D', D],
954
+ ['E', E],
955
+ ['F', F],
956
+ ]}
957
/>,
958
);
959
@@ -1021,7 +1035,15 @@ describe('ReactSuspenseList', () => {
1035
await F.resolve();
1036
1037
// We can also delete some items.
1024
- ReactNoop.render(<Foo items={[['D', D], ['E', E], ['F', F]]} />);
1038
+ ReactNoop.render(
1039
+ <Foo
1040
+ items={[
1041
+ ['D', D],
1042
+ ['E', E],
1043
+ ['F', F],
1044
+ ]}
1045
+ />,
1046
+ );
1047
1048
expect(Scheduler).toFlushAndYield(['D', 'E', 'F']);
1049
@@ -1093,7 +1115,14 @@ describe('ReactSuspenseList', () => {
1115
// Update items in the beginning, middle and end to start suspending.
1116
ReactNoop.render(
1117
<Foo
1096
- items={[['A', A], ['B', B], ['C', Cs], ['D', D], ['E', Es], ['F', F]]}
1118
+ items={[
1119
+ ['A', A],
1120
+ ['B', B],
1121
+ ['C', Cs],
1122
+ ['D', D],
1123
+ ['E', Es],
1124
+ ['F', F],
1125
+ ]}
1126
/>,
1127
);
1128
@@ -1468,7 +1497,14 @@ describe('ReactSuspenseList', () => {
1497
);
1498
}
1499
1471
- ReactNoop.render(<Foo items={[['A', A], ['D', D]]} />);
1500
+ ReactNoop.render(
1501
+ <Foo
1502
+ items={[
1503
+ ['A', A],
1504
+ ['D', D],
1505
+ ]}
1506
+ />,
1507
+ );
1508
1509
await A.resolve();
1510
await D.resolve();
@@ -1486,7 +1522,14 @@ describe('ReactSuspenseList', () => {
1522
// For the second render, we're going to insert items in the middle and end.
1523
ReactNoop.render(
1524
<Foo
1489
- items={[['A', A], ['B', B], ['C', C], ['D', D], ['E', E], ['F', F]]}
1525
+ items={[
1526
+ ['A', A],
1527
+ ['B', B],
1528
+ ['C', C],
1529
+ ['D', D],
1530
+ ['E', E],
1531
+ ['F', F],
1532
+ ]}
1533
/>,
1534
);
1535
@@ -1596,7 +1639,14 @@ describe('ReactSuspenseList', () => {
1639
);
1640
}
1641
1599
- ReactNoop.render(<Foo items={[['C', C], ['F', F]]} />);
1642
+ ReactNoop.render(
1643
+ <Foo
1644
+ items={[
1645
+ ['C', C],
1646
+ ['F', F],
1647
+ ]}
1648
+ />,
1649
+ );
1650
1651
await C.resolve();
1652
await F.resolve();
@@ -1614,7 +1664,14 @@ describe('ReactSuspenseList', () => {
1664
// For the second render, we're going to insert items in the middle and end.
1665
ReactNoop.render(
1666
<Foo
1617
- items={[['A', A], ['B', B], ['C', C], ['D', D], ['E', E], ['F', F]]}
1667
+ items={[
1668
+ ['A', A],
1669
+ ['B', B],
1670
+ ['C', C],
1671
+ ['D', D],
1672
+ ['E', E],
1673
+ ['F', F],
1674
+ ]}
1675
/>,
1676
);
1677
@@ -1733,7 +1790,14 @@ describe('ReactSuspenseList', () => {
1790
);
1791
}
1792
1736
- ReactNoop.render(<Foo items={[['A', A], ['D', SyncD]]} />);
1793
+ ReactNoop.render(
1794
+ <Foo
1795
+ items={[
1796
+ ['A', A],
1797
+ ['D', SyncD],
1798
+ ]}
1799
+ />,
1800
+ );
1801
1802
await A.resolve();
1803
@@ -1751,7 +1815,14 @@ describe('ReactSuspenseList', () => {
1815
// Note that D now suspends even though it didn't in the first pass.
1816
ReactNoop.render(
1817
<Foo
1754
- items={[['A', A], ['B', B], ['C', C], ['D', D], ['E', E], ['F', F]]}
1818
+ items={[
1819
+ ['A', A],
1820
+ ['B', B],
1821
+ ['C', C],
1822
+ ['D', D],
1823
+ ['E', E],
1824
+ ['F', F],
1825
+ ]}
1826
/>,
1827
);
1828
packages/react-reconciler/src/__tests__/ReactSuspensePlaceholder-test.internal.js
+45
-38
@@ -34,46 +34,53 @@ describe('ReactSuspensePlaceholder', () => {
34
Profiler = React.Profiler;
35
Suspense = React.Suspense;
36
37
- TextResource = ReactCache.unstable_createResource(([text, ms = 0]) => {
38
- let listeners = null;
39
- let status = 'pending';
40
- let value = null;
41
- return {
42
- then(resolve, reject) {
43
- switch (status) {
44
- case 'pending': {
45
- if (listeners === null) {
46
- listeners = [{resolve, reject}];
47
- setTimeout(() => {
48
- if (textResourceShouldFail) {
49
- Scheduler.unstable_yieldValue(`Promise rejected [${text}]`);
50
- status = 'rejected';
51
- value = new Error('Failed to load: ' + text);
52
- listeners.forEach(listener => listener.reject(value));
53
- } else {
54
- Scheduler.unstable_yieldValue(`Promise resolved [${text}]`);
55
- status = 'resolved';
56
- value = text;
57
- listeners.forEach(listener => listener.resolve(value));
58
- }
59
- }, ms);
60
- } else {
61
- listeners.push({resolve, reject});
37
+ TextResource = ReactCache.unstable_createResource(
38
+ ([text, ms = 0]) => {
39
+ let listeners = null;
40
+ let status = 'pending';
41
+ let value = null;
42
+ return {
43
+ then(resolve, reject) {
44
+ switch (status) {
45
+ case 'pending': {
46
+ if (listeners === null) {
47
+ listeners = [{resolve, reject}];
48
+ setTimeout(() => {
49
+ if (textResourceShouldFail) {
50
+ Scheduler.unstable_yieldValue(
51
+ `Promise rejected [${text}]`,
52
+ );
53
+ status = 'rejected';
54
+ value = new Error('Failed to load: ' + text);
55
+ listeners.forEach(listener => listener.reject(value));
56
+ } else {
57
+ Scheduler.unstable_yieldValue(
58
+ `Promise resolved [${text}]`,
59
+ );
60
+ status = 'resolved';
61
+ value = text;
62
+ listeners.forEach(listener => listener.resolve(value));
63
+ }
64
+ }, ms);
65
+ } else {
66
+ listeners.push({resolve, reject});
67
+ }
68
+ break;
69
+ }
70
+ case 'resolved': {
71
+ resolve(value);
72
+ break;
73
+ }
74
+ case 'rejected': {
75
+ reject(value);
76
+ break;
77
}
63
- break;
64
- }
65
- case 'resolved': {
66
- resolve(value);
67
- break;
68
- }
69
- case 'rejected': {
70
- reject(value);
71
- break;
78
}
73
- }
74
- },
75
- };
76
- }, ([text, ms]) => text);
79
+ },
80
+ };
81
+ },
82
+ ([text, ms]) => text,
83
+ );
84
textResourceShouldFail = false;
85
});
86
packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.internal.js
+46
-54
@@ -28,19 +28,22 @@ describe('ReactSuspenseWithNoopRenderer', () => {
28
ReactCache = require('react-cache');
29
Suspense = React.Suspense;
30
31
- TextResource = ReactCache.unstable_createResource(([text, ms = 0]) => {
32
- return new Promise((resolve, reject) =>
33
- setTimeout(() => {
34
- if (textResourceShouldFail) {
35
- Scheduler.unstable_yieldValue(`Promise rejected [${text}]`);
36
- reject(new Error('Failed to load: ' + text));
37
- } else {
38
- Scheduler.unstable_yieldValue(`Promise resolved [${text}]`);
39
- resolve(text);
40
- }
41
- }, ms),
42
- );
43
- }, ([text, ms]) => text);
31
+ TextResource = ReactCache.unstable_createResource(
32
+ ([text, ms = 0]) => {
33
+ return new Promise((resolve, reject) =>
34
+ setTimeout(() => {
35
+ if (textResourceShouldFail) {
36
+ Scheduler.unstable_yieldValue(`Promise rejected [${text}]`);
37
+ reject(new Error('Failed to load: ' + text));
38
+ } else {
39
+ Scheduler.unstable_yieldValue(`Promise resolved [${text}]`);
40
+ resolve(text);
41
+ }
42
+ }, ms),
43
+ );
44
+ },
45
+ ([text, ms]) => text,
46
+ );
47
textResourceShouldFail = false;
48
});
49
@@ -1514,50 +1517,38 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1517
1518
it('does not call lifecycles of a suspended component (hooks)', async () => {
1519
function TextWithLifecycle(props) {
1517
- React.useLayoutEffect(
1518
- () => {
1519
- Scheduler.unstable_yieldValue(`Layout Effect [${props.text}]`);
1520
- return () => {
1521
- Scheduler.unstable_yieldValue(
1522
- `Destroy Layout Effect [${props.text}]`,
1523
- );
1524
- };
1525
- },
1526
- [props.text],
1527
- );
1528
- React.useEffect(
1529
- () => {
1530
- Scheduler.unstable_yieldValue(`Effect [${props.text}]`);
1531
- return () => {
1532
- Scheduler.unstable_yieldValue(`Destroy Effect [${props.text}]`);
1533
- };
1534
- },
1535
- [props.text],
1536
- );
1520
+ React.useLayoutEffect(() => {
1521
+ Scheduler.unstable_yieldValue(`Layout Effect [${props.text}]`);
1522
+ return () => {
1523
+ Scheduler.unstable_yieldValue(
1524
+ `Destroy Layout Effect [${props.text}]`,
1525
+ );
1526
+ };
1527
+ }, [props.text]);
1528
+ React.useEffect(() => {
1529
+ Scheduler.unstable_yieldValue(`Effect [${props.text}]`);
1530
+ return () => {
1531
+ Scheduler.unstable_yieldValue(`Destroy Effect [${props.text}]`);
1532
+ };
1533
+ }, [props.text]);
1534
return <Text {...props} />;
1535
}
1536
1537
function AsyncTextWithLifecycle(props) {
1541
- React.useLayoutEffect(
1542
- () => {
1543
- Scheduler.unstable_yieldValue(`Layout Effect [${props.text}]`);
1544
- return () => {
1545
- Scheduler.unstable_yieldValue(
1546
- `Destroy Layout Effect [${props.text}]`,
1547
- );
1548
- };
1549
- },
1550
- [props.text],
1551
- );
1552
- React.useEffect(
1553
- () => {
1554
- Scheduler.unstable_yieldValue(`Effect [${props.text}]`);
1555
- return () => {
1556
- Scheduler.unstable_yieldValue(`Destroy Effect [${props.text}]`);
1557
- };
1558
- },
1559
- [props.text],
1560
- );
1538
+ React.useLayoutEffect(() => {
1539
+ Scheduler.unstable_yieldValue(`Layout Effect [${props.text}]`);
1540
+ return () => {
1541
+ Scheduler.unstable_yieldValue(
1542
+ `Destroy Layout Effect [${props.text}]`,
1543
+ );
1544
+ };
1545
+ }, [props.text]);
1546
+ React.useEffect(() => {
1547
+ Scheduler.unstable_yieldValue(`Effect [${props.text}]`);
1548
+ return () => {
1549
+ Scheduler.unstable_yieldValue(`Destroy Effect [${props.text}]`);
1550
+ };
1551
+ }, [props.text]);
1552
const text = props.text;
1553
const ms = props.ms;
1554
try {
@@ -2896,7 +2887,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2887
expect(ReactNoop).toMatchRenderedOutput(
2888
<>
2889
<div hidden={true}>
2899
- <span prop="A" />Offscreen
2890
+ <span prop="A" />
2891
+ Offscreen
2892
</div>
2893
<span prop="A" />
2894
</>,
packages/react-refresh/src/__tests__/ReactFresh-test.js
+4
-2
@@ -1817,12 +1817,14 @@ describe('ReactFresh', () => {
1817
<span />
1818
Hello
1819
<span />
1820
- </HelloV1>,
1820
+ </HelloV1>
1821
+ ,
1822
<HelloV1>
1823
<>
1824
<HelloV1 />
1825
</>
1825
- </HelloV1>,
1826
+ </HelloV1>
1827
+ ,
1828
</div>,
1829
<HelloV1>
1830
<HelloV1>
packages/react-test-renderer/src/ReactShallowRenderer.js
+9
-7
@@ -295,9 +295,10 @@ class ReactShallowRenderer {
295
first: null,
296
dispatch: null,
297
});
298
- const dispatch: Dispatch<
299
- A,
300
- > = (queue.dispatch = (this._dispatchAction.bind(this, queue): any));
298
+ const dispatch: Dispatch<A> = (queue.dispatch = (this._dispatchAction.bind(
299
+ this,
300
+ queue,
301
+ ): any));
302
return [workInProgressHook.memoizedState, dispatch];
303
}
304
};
@@ -529,7 +530,7 @@ class ReactShallowRenderer {
530
'ReactShallowRenderer render(): Invalid component element.%s',
531
typeof element === 'function'
532
? ' Instead of passing a component class, make sure to instantiate ' +
532
- 'it by passing it to React.createElement.'
533
+ 'it by passing it to React.createElement.'
534
: '',
535
);
536
element = ((element: any): ReactElement);
@@ -543,14 +544,15 @@ class ReactShallowRenderer {
544
);
545
invariant(
546
isForwardRef(element) ||
546
- (typeof element.type === 'function' || isMemo(element)),
547
+ typeof element.type === 'function' ||
548
+ isMemo(element),
549
'ReactShallowRenderer render(): Shallow rendering works only with custom ' +
550
'components, but the provided element type was `%s`.',
551
Array.isArray(element.type)
552
? 'array'
553
: element.type === null
552
- ? 'null'
553
- : typeof element.type,
554
+ ? 'null'
555
+ : typeof element.type,
556
);
557
558
if (this._rendering) {
packages/react/src/ReactHooks.js
+2
-2
@@ -45,8 +45,8 @@ export function useContext<T>(
45
unstable_observedBits,
46
typeof unstable_observedBits === 'number' && Array.isArray(arguments[2])
47
? '\n\nDid you call array.map(useContext)? ' +
48
- 'Calling Hooks inside a loop is not supported. ' +
49
- 'Learn more at https://fb.me/rules-of-hooks'
48
+ 'Calling Hooks inside a loop is not supported. ' +
49
+ 'Learn more at https://fb.me/rules-of-hooks'
50
: '',
51
);
52
}
packages/react/src/__tests__/ReactDOMTracing-test.internal.js
+19
-25
@@ -73,17 +73,14 @@ describe('ReactDOMTracing', () => {
73
const Child = () => {
74
const [didMount, setDidMount] = React.useState(false);
75
Scheduler.unstable_yieldValue('Child');
76
- React.useEffect(
77
- () => {
78
- if (didMount) {
79
- Scheduler.unstable_yieldValue('Child:update');
80
- } else {
81
- Scheduler.unstable_yieldValue('Child:mount');
82
- setDidMount(true);
83
- }
84
- },
85
- [didMount],
86
- );
76
+ React.useEffect(() => {
77
+ if (didMount) {
78
+ Scheduler.unstable_yieldValue('Child:update');
79
+ } else {
80
+ Scheduler.unstable_yieldValue('Child:mount');
81
+ setDidMount(true);
82
+ }
83
+ }, [didMount]);
84
return <div />;
85
};
86
@@ -219,20 +216,17 @@ describe('ReactDOMTracing', () => {
216
const Child = () => {
217
const [didMount, setDidMount] = React.useState(false);
218
Scheduler.unstable_yieldValue('Child');
222
- React.useLayoutEffect(
223
- () => {
224
- if (didMount) {
225
- Scheduler.unstable_yieldValue('Child:update');
226
- } else {
227
- Scheduler.unstable_yieldValue('Child:mount');
228
- Scheduler.unstable_runWithPriority(
229
- Scheduler.unstable_IdlePriority,
230
- () => setDidMount(true),
231
- );
232
- }
233
- },
234
- [didMount],
235
- );
219
+ React.useLayoutEffect(() => {
220
+ if (didMount) {
221
+ Scheduler.unstable_yieldValue('Child:update');
222
+ } else {
223
+ Scheduler.unstable_yieldValue('Child:mount');
224
+ Scheduler.unstable_runWithPriority(
225
+ Scheduler.unstable_IdlePriority,
226
+ () => setDidMount(true),
227
+ );
228
+ }
229
+ }, [didMount]);
230
return <div />;
231
};
232
packages/react/src/__tests__/ReactES6Class-test.js
+6
-2
@@ -521,11 +521,15 @@ describe('ReactES6Class', () => {
521
522
it('should throw AND warn when trying to access classic APIs', () => {
523
const instance = test(<Inner name="foo" />, 'DIV', 'foo');
524
- expect(() => expect(() => instance.replaceState({})).toThrow()).toWarnDev(
524
+ expect(() =>
525
+ expect(() => instance.replaceState({})).toThrow(),
526
+ ).toWarnDev(
527
'replaceState(...) is deprecated in plain JavaScript React classes',
528
{withoutStack: true},
529
);
528
- expect(() => expect(() => instance.isMounted()).toThrow()).toWarnDev(
530
+ expect(() =>
531
+ expect(() => instance.isMounted()).toThrow(),
532
+ ).toWarnDev(
533
'isMounted(...) is deprecated in plain JavaScript React classes',
534
{withoutStack: true},
535
);
packages/react/src/__tests__/ReactElement-test.js
+4
-2
@@ -42,7 +42,7 @@ describe('ReactElement', () => {
42
});
43
44
it('uses the fallback value when in an environment without Symbol', () => {
45
- expect(<div />.$$typeof).toBe(0xeac7);
45
+ expect((<div />).$$typeof).toBe(0xeac7);
46
});
47
48
it('returns a complete element according to spec', () => {
@@ -85,7 +85,9 @@ describe('ReactElement', () => {
85
86
it('should warn when `key` is being accessed on a host element', () => {
87
const element = <div key="3" />;
88
- expect(() => void element.props.key).toErrorDev(
88
+ expect(
89
+ () => void element.props.key,
90
+ ).toErrorDev(
91
'div: `key` is not a prop. Trying to access it will result ' +
92
'in `undefined` being returned. If you need to access the same ' +
93
'value within the child component, you should pass it as a different ' +
packages/react/src/__tests__/ReactElementJSX-test.internal.js
+3
-1
@@ -228,7 +228,9 @@ describe('ReactElement.jsx', () => {
228
229
it('should warn when `key` is being accessed on a host element', () => {
230
const element = React.jsxs('div', {}, '3');
231
- expect(() => void element.props.key).toErrorDev(
231
+ expect(
232
+ () => void element.props.key,
233
+ ).toErrorDev(
234
'div: `key` is not a prop. Trying to access it will result ' +
235
'in `undefined` being returned. If you need to access the same ' +
236
'value within the child component, you should pass it as a different ' +
packages/react/src/__tests__/ReactElementValidator-test.internal.js
+6
-4
@@ -439,7 +439,9 @@ describe('ReactElementValidator', () => {
439
}
440
441
let TestFactory = React.createFactory(TestComponent);
442
- expect(() => TestFactory.type).toWarnDev(
442
+ expect(
443
+ () => TestFactory.type,
444
+ ).toWarnDev(
445
'Warning: Factory.type is deprecated. Access the class directly before ' +
446
'passing it to createFactory.',
447
{withoutStack: true},
@@ -489,7 +491,7 @@ describe('ReactElementValidator', () => {
491
// shouldn't blow up either.
492
493
const child = {
492
- $$typeof: <div />.$$typeof,
494
+ $$typeof: (<div />).$$typeof,
495
type: 'span',
496
key: null,
497
ref: null,
@@ -497,13 +499,13 @@ describe('ReactElementValidator', () => {
499
_owner: null,
500
};
501
500
- void <div>{[child]}</div>;
502
+ void (<div>{[child]}</div>);
503
});
504
505
it('does not blow up on key warning with undefined type', () => {
506
const Foo = undefined;
507
expect(() => {
506
- void <Foo>{[<div />]}</Foo>;
508
+ void (<Foo>{[<div />]}</Foo>);
509
}).toErrorDev(
510
'Warning: React.createElement: type is invalid -- expected a string ' +
511
'(for built-in components) or a class/function (for composite ' +
packages/react/src/__tests__/ReactJSXElementValidator-test.js
+11
-5
@@ -143,7 +143,7 @@ describe('ReactJSXElementValidator', () => {
143
});
144
145
it('does not warn when the child array contains non-elements', () => {
146
- void <Component>{[{}, {}]}</Component>;
146
+ void (<Component>{[{}, {}]}</Component>);
147
});
148
149
it('should give context for PropType errors in nested components.', () => {
@@ -210,7 +210,9 @@ describe('ReactJSXElementValidator', () => {
210
const Null = null;
211
const True = true;
212
const Div = 'div';
213
- expect(() => void <Undefined />).toErrorDev(
213
+ expect(
214
+ () => void (<Undefined />),
215
+ ).toErrorDev(
216
'Warning: React.createElement: type is invalid -- expected a string ' +
217
'(for built-in components) or a class/function (for composite ' +
218
'components) but got: undefined. You likely forgot to export your ' +
@@ -219,14 +221,18 @@ describe('ReactJSXElementValidator', () => {
221
'\n\nCheck your code at **.',
222
{withoutStack: true},
223
);
222
- expect(() => void <Null />).toErrorDev(
224
+ expect(
225
+ () => void (<Null />),
226
+ ).toErrorDev(
227
'Warning: React.createElement: type is invalid -- expected a string ' +
228
'(for built-in components) or a class/function (for composite ' +
229
'components) but got: null.' +
230
'\n\nCheck your code at **.',
231
{withoutStack: true},
232
);
229
- expect(() => void <True />).toErrorDev(
233
+ expect(
234
+ () => void (<True />),
235
+ ).toErrorDev(
236
'Warning: React.createElement: type is invalid -- expected a string ' +
237
'(for built-in components) or a class/function (for composite ' +
238
'components) but got: boolean.' +
@@ -234,7 +240,7 @@ describe('ReactJSXElementValidator', () => {
240
{withoutStack: true},
241
);
242
// No error expected
237
- void <Div />;
243
+ void (<Div />);
244
});
245
246
it('should check default prop values', () => {
packages/react/src/__tests__/ReactProfiler-test.internal.js
+19
-13
@@ -65,15 +65,18 @@ function loadModules({
65
66
resourcePromise = null;
67
68
- TextResource = ReactCache.unstable_createResource(([text, ms = 0]) => {
69
- resourcePromise = new Promise((resolve, reject) =>
70
- setTimeout(() => {
71
- Scheduler.unstable_yieldValue(`Promise resolved [${text}]`);
72
- resolve(text);
73
- }, ms),
74
- );
75
- return resourcePromise;
76
- }, ([text, ms]) => text);
68
+ TextResource = ReactCache.unstable_createResource(
69
+ ([text, ms = 0]) => {
70
+ resourcePromise = new Promise((resolve, reject) =>
71
+ setTimeout(() => {
72
+ Scheduler.unstable_yieldValue(`Promise resolved [${text}]`);
73
+ resolve(text);
74
+ }, ms),
75
+ );
76
+ return resourcePromise;
77
+ },
78
+ ([text, ms]) => text,
79
+ );
80
81
AsyncText = ({ms, text}) => {
82
try {
@@ -297,10 +300,13 @@ describe('Profiler', () => {
300
it('does not report work done on a sibling', () => {
301
const callback = jest.fn();
302
300
- const DoesNotUpdate = React.memo(function DoesNotUpdateInner() {
301
- Scheduler.unstable_advanceTime(10);
302
- return null;
303
- }, () => true);
303
+ const DoesNotUpdate = React.memo(
304
+ function DoesNotUpdateInner() {
305
+ Scheduler.unstable_advanceTime(10);
306
+ return null;
307
+ },
308
+ () => true,
309
+ );
310
311
let updateProfilerSibling;
312
packages/react/src/__tests__/ReactStrictMode-test.js
+9
-3
@@ -535,13 +535,17 @@ Please update the following components: Parent`,
535
const container = document.createElement('div');
536
const root = ReactDOM.createRoot(container);
537
root.render(<AsyncRoot foo={true} />);
538
- expect(() => Scheduler.unstable_flushAll()).toErrorDev(
538
+ expect(() =>
539
+ Scheduler.unstable_flushAll(),
540
+ ).toErrorDev(
541
'Using UNSAFE_componentWillMount in strict mode is not recommended',
542
{withoutStack: true},
543
);
544
545
root.render(<AsyncRoot foo={false} />);
544
- expect(() => Scheduler.unstable_flushAll()).toErrorDev(
546
+ expect(() =>
547
+ Scheduler.unstable_flushAll(),
548
+ ).toErrorDev(
549
'Using UNSAFE_componentWillMount in strict mode is not recommended',
550
{withoutStack: true},
551
);
@@ -592,7 +596,9 @@ Please update the following components: Parent`,
596
597
const container = document.createElement('div');
598
595
- expect(() => ReactDOM.render(<SyncRoot />, container)).toErrorDev(
599
+ expect(() =>
600
+ ReactDOM.render(<SyncRoot />, container),
601
+ ).toErrorDev(
602
'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended',
603
{withoutStack: true},
604
);
packages/react/src/__tests__/createReactClassIntegration-test.internal.js
+6
-5
@@ -50,10 +50,9 @@ describe('create-react-class-integration', () => {
50
render: () => null,
51
});
52
53
- expect(() => ReactNative.render(<View />, 1)).toWarnDev(
54
- 'componentWillMount has been renamed',
55
- {withoutStack: true},
56
- );
53
+ expect(() =>
54
+ ReactNative.render(<View />, 1),
55
+ ).toWarnDev('componentWillMount has been renamed', {withoutStack: true});
56
});
57
58
it('should warn if users specify their own legacy componentWillReceiveProps', () => {
@@ -66,7 +65,9 @@ describe('create-react-class-integration', () => {
65
66
expect(() => ReactNative.render(<View />, 1)).toWarnDev(
67
'componentWillReceiveProps has been renamed',
69
- {withoutStack: true},
68
+ {
69
+ withoutStack: true,
70
+ },
71
);
72
});
73
});
packages/react/src/__tests__/createReactClassIntegration-test.js
+6
-2
@@ -361,7 +361,9 @@ describe('create-react-class-integration', () => {
361
},
362
});
363
364
- expect(() => expect(() => Component()).toThrow()).toErrorDev(
364
+ expect(() =>
365
+ expect(() => Component()).toThrow(),
366
+ ).toErrorDev(
367
'Warning: Something is calling a React component directly. Use a ' +
368
'factory or JSX instead. See: https://fb.me/react-legacyfactory',
369
{withoutStack: true},
@@ -717,7 +719,9 @@ describe('create-react-class-integration', () => {
719
720
const container = document.createElement('div');
721
720
- expect(() => ReactDOM.render(<Component />, container)).toErrorDev(
722
+ expect(() =>
723
+ ReactDOM.render(<Component />, container),
724
+ ).toErrorDev(
725
'Warning: MyComponent: isMounted is deprecated. Instead, make sure to ' +
726
'clean up subscriptions and pending requests in componentWillUnmount ' +
727
'to prevent memory leaks.',
packages/react/src/__tests__/forwardRef-test.js
+24
-8
@@ -126,22 +126,30 @@ describe('forwardRef', () => {
126
});
127
128
it('should warn if not provided a callback during creation', () => {
129
- expect(() => React.forwardRef(undefined)).toErrorDev(
129
+ expect(() =>
130
+ React.forwardRef(undefined),
131
+ ).toErrorDev(
132
'forwardRef requires a render function but was given undefined.',
133
{withoutStack: true},
134
);
135
expect(() => React.forwardRef(null)).toErrorDev(
136
'forwardRef requires a render function but was given null.',
135
- {withoutStack: true},
137
+ {
138
+ withoutStack: true,
139
+ },
140
);
137
- expect(() => React.forwardRef('foo')).toErrorDev(
141
+ expect(() =>
142
+ React.forwardRef('foo'),
143
+ ).toErrorDev(
144
'forwardRef requires a render function but was given string.',
145
{withoutStack: true},
146
);
147
});
148
149
it('should warn if no render function is provided', () => {
144
- expect(React.forwardRef).toErrorDev(
150
+ expect(
151
+ React.forwardRef,
152
+ ).toErrorDev(
153
'forwardRef requires a render function but was given undefined.',
154
{withoutStack: true},
155
);
@@ -158,12 +166,16 @@ describe('forwardRef', () => {
166
}
167
renderWithDefaultProps.defaultProps = {};
168
161
- expect(() => React.forwardRef(renderWithPropTypes)).toErrorDev(
169
+ expect(() =>
170
+ React.forwardRef(renderWithPropTypes),
171
+ ).toErrorDev(
172
'forwardRef render functions do not support propTypes or defaultProps. ' +
173
'Did you accidentally pass a React component?',
174
{withoutStack: true},
175
);
166
- expect(() => React.forwardRef(renderWithDefaultProps)).toErrorDev(
176
+ expect(() =>
177
+ React.forwardRef(renderWithDefaultProps),
178
+ ).toErrorDev(
179
'forwardRef render functions do not support propTypes or defaultProps. ' +
180
'Did you accidentally pass a React component?',
181
{withoutStack: true},
@@ -179,7 +191,9 @@ describe('forwardRef', () => {
191
it('should warn if the render function provided does not use the forwarded ref parameter', () => {
192
const arityOfOne = props => <div {...props} />;
193
182
- expect(() => React.forwardRef(arityOfOne)).toErrorDev(
194
+ expect(() =>
195
+ React.forwardRef(arityOfOne),
196
+ ).toErrorDev(
197
'forwardRef render functions accept exactly two parameters: props and ref. ' +
198
'Did you forget to use the ref parameter?',
199
{withoutStack: true},
@@ -194,7 +208,9 @@ describe('forwardRef', () => {
208
it('should warn if the render function provided expects to use more than two parameters', () => {
209
const arityOfThree = (props, ref, x) => <div {...props} ref={ref} x={x} />;
210
197
- expect(() => React.forwardRef(arityOfThree)).toErrorDev(
211
+ expect(() =>
212
+ React.forwardRef(arityOfThree),
213
+ ).toErrorDev(
214
'forwardRef render functions accept exactly two parameters: props and ref. ' +
215
'Any additional parameter will be undefined.',
216
{withoutStack: true},
packages/scheduler/npm/umd/scheduler-tracing.development.js
+2
-2
@@ -14,8 +14,8 @@
14
typeof exports === 'object' && typeof module !== 'undefined'
15
? (module.exports = factory(require('react')))
16
: typeof define === 'function' && define.amd // eslint-disable-line no-undef
17
- ? define(['react'], factory) // eslint-disable-line no-undef
18
- : (global.SchedulerTracing = factory(global));
17
+ ? define(['react'], factory) // eslint-disable-line no-undef
18
+ : (global.SchedulerTracing = factory(global));
19
})(this, function(global) {
20
function unstable_clear() {
21
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.SchedulerTracing.unstable_clear.apply(
packages/scheduler/npm/umd/scheduler-tracing.production.min.js
+2
-2
@@ -14,8 +14,8 @@
14
typeof exports === 'object' && typeof module !== 'undefined'
15
? (module.exports = factory(require('react')))
16
: typeof define === 'function' && define.amd // eslint-disable-line no-undef
17
- ? define(['react'], factory) // eslint-disable-line no-undef
18
- : (global.SchedulerTracing = factory(global));
17
+ ? define(['react'], factory) // eslint-disable-line no-undef
18
+ : (global.SchedulerTracing = factory(global));
19
})(this, function(global) {
20
function unstable_clear() {
21
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.SchedulerTracing.unstable_clear.apply(
packages/scheduler/npm/umd/scheduler-tracing.profiling.min.js
+2
-2
@@ -14,8 +14,8 @@
14
typeof exports === 'object' && typeof module !== 'undefined'
15
? (module.exports = factory(require('react')))
16
: typeof define === 'function' && define.amd // eslint-disable-line no-undef
17
- ? define(['react'], factory) // eslint-disable-line no-undef
18
- : (global.SchedulerTracing = factory(global));
17
+ ? define(['react'], factory) // eslint-disable-line no-undef
18
+ : (global.SchedulerTracing = factory(global));
19
})(this, function(global) {
20
function unstable_clear() {
21
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.SchedulerTracing.unstable_clear.apply(
packages/scheduler/npm/umd/scheduler.development.js
+2
-2
@@ -16,8 +16,8 @@
16
typeof exports === 'object' && typeof module !== 'undefined'
17
? (module.exports = factory(require('react')))
18
: typeof define === 'function' && define.amd // eslint-disable-line no-undef
19
- ? define(['react'], factory) // eslint-disable-line no-undef
20
- : (global.Scheduler = factory(global));
19
+ ? define(['react'], factory) // eslint-disable-line no-undef
20
+ : (global.Scheduler = factory(global));
21
})(this, function(global) {
22
function unstable_now() {
23
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_now.apply(
packages/scheduler/npm/umd/scheduler.production.min.js
+2
-2
@@ -16,8 +16,8 @@
16
typeof exports === 'object' && typeof module !== 'undefined'
17
? (module.exports = factory(require('react')))
18
: typeof define === 'function' && define.amd // eslint-disable-line no-undef
19
- ? define(['react'], factory) // eslint-disable-line no-undef
20
- : (global.Scheduler = factory(global));
19
+ ? define(['react'], factory) // eslint-disable-line no-undef
20
+ : (global.Scheduler = factory(global));
21
})(this, function(global) {
22
function unstable_now() {
23
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_now.apply(
packages/scheduler/npm/umd/scheduler.profiling.min.js
+2
-2
@@ -16,8 +16,8 @@
16
typeof exports === 'object' && typeof module !== 'undefined'
17
? (module.exports = factory(require('react')))
18
: typeof define === 'function' && define.amd // eslint-disable-line no-undef
19
- ? define(['react'], factory) // eslint-disable-line no-undef
20
- : (global.Scheduler = factory(global));
19
+ ? define(['react'], factory) // eslint-disable-line no-undef
20
+ : (global.Scheduler = factory(global));
21
})(this, function(global) {
22
function unstable_now() {
23
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_now.apply(
packages/scheduler/src/SchedulerProfiling.js
+3
-3
@@ -21,9 +21,9 @@ export const sharedProfilingBuffer = enableProfiling
21
typeof SharedArrayBuffer === 'function'
22
? new SharedArrayBuffer(profilingStateSize * Int32Array.BYTES_PER_ELEMENT)
23
: // $FlowFixMe Flow doesn't know about ArrayBuffer
24
- typeof ArrayBuffer === 'function'
25
- ? new ArrayBuffer(profilingStateSize * Int32Array.BYTES_PER_ELEMENT)
26
- : null // Don't crash the init path on IE9
24
+ typeof ArrayBuffer === 'function'
25
+ ? new ArrayBuffer(profilingStateSize * Int32Array.BYTES_PER_ELEMENT)
26
+ : null // Don't crash the init path on IE9
27
: null;
28
29
const profilingState =
packages/scheduler/src/__tests__/Scheduler-test.js
+29
-5
@@ -154,7 +154,11 @@ describe('Scheduler', () => {
154
});
155
156
let didYield = false;
157
- const tasks = [['C1', 100], ['C2', 100], ['C3', 100]];
157
+ const tasks = [
158
+ ['C1', 100],
159
+ ['C2', 100],
160
+ ['C3', 100],
161
+ ];
162
const C = () => {
163
while (tasks.length > 0) {
164
const [label, ms] = tasks.shift();
@@ -188,7 +192,12 @@ describe('Scheduler', () => {
192
});
193
194
it('continuation callbacks inherit the expiration of the previous callback', () => {
191
- const tasks = [['A', 125], ['B', 124], ['C', 100], ['D', 100]];
195
+ const tasks = [
196
+ ['A', 125],
197
+ ['B', 124],
198
+ ['C', 100],
199
+ ['D', 100],
200
+ ];
201
const work = () => {
202
while (tasks.length > 0) {
203
const [label, ms] = tasks.shift();
@@ -212,7 +221,12 @@ describe('Scheduler', () => {
221
});
222
223
it('continuations are interrupted by higher priority work', () => {
215
- const tasks = [['A', 100], ['B', 100], ['C', 100], ['D', 100]];
224
+ const tasks = [
225
+ ['A', 100],
226
+ ['B', 100],
227
+ ['C', 100],
228
+ ['D', 100],
229
+ ];
230
const work = () => {
231
while (tasks.length > 0) {
232
const [label, ms] = tasks.shift();
@@ -238,7 +252,12 @@ describe('Scheduler', () => {
252
'continuations are interrupted by higher priority work scheduled ' +
253
'inside an executing callback',
254
() => {
241
- const tasks = [['A', 100], ['B', 100], ['C', 100], ['D', 100]];
255
+ const tasks = [
256
+ ['A', 100],
257
+ ['B', 100],
258
+ ['C', 100],
259
+ ['D', 100],
260
+ ];
261
const work = () => {
262
while (tasks.length > 0) {
263
const task = tasks.shift();
@@ -631,7 +650,12 @@ describe('Scheduler', () => {
650
);
651
652
// Schedule a time-sliced task at default priority.
634
- const tasks = [['A', 100], ['B', 100], ['C', 100], ['D', 100]];
653
+ const tasks = [
654
+ ['A', 100],
655
+ ['B', 100],
656
+ ['C', 100],
657
+ ['D', 100],
658
+ ];
659
const work = () => {
660
while (tasks.length > 0) {
661
const task = tasks.shift();
packages/shared/objectIs.js
+1
-1
@@ -17,4 +17,4 @@ function is(x: any, y: any) {
17
);
18
}
19
20
-export default (typeof Object.is === 'function' ? Object.is : is);
20
+export default typeof Object.is === 'function' ? Object.is : is;
packages/use-subscription/src/useSubscription.js
+50
-53
@@ -67,61 +67,58 @@ export function useSubscription<Value>({
67
// This also has an added benefit when multiple components are subscribed to the same source:
68
// It allows each of the event handlers to safely schedule work without potentially removing an another handler.
69
// (Learn more at https://codesandbox.io/s/k0yvr5970o)
70
- useEffect(
71
- () => {
72
- let didUnsubscribe = false;
73
-
74
- const checkForUpdates = () => {
75
- // It's possible that this callback will be invoked even after being unsubscribed,
76
- // if it's removed as a result of a subscription event/update.
77
- // In this case, React will log a DEV warning about an update from an unmounted component.
78
- // We can avoid triggering that warning with this check.
79
- if (didUnsubscribe) {
80
- return;
70
+ useEffect(() => {
71
+ let didUnsubscribe = false;
72
+
73
+ const checkForUpdates = () => {
74
+ // It's possible that this callback will be invoked even after being unsubscribed,
75
+ // if it's removed as a result of a subscription event/update.
76
+ // In this case, React will log a DEV warning about an update from an unmounted component.
77
+ // We can avoid triggering that warning with this check.
78
+ if (didUnsubscribe) {
79
+ return;
80
+ }
81
+
82
+ // We use a state updater function to avoid scheduling work for a stale source.
83
+ // However it's important to eagerly read the currently value,
84
+ // so that all scheduled work shares the same value (in the event of multiple subscriptions).
85
+ // This avoids visual "tearing" when a mutation happens during a (concurrent) render.
86
+ const value = getCurrentValue();
87
+
88
+ setState(prevState => {
89
+ // Ignore values from stale sources!
90
+ // Since we subscribe an unsubscribe in a passive effect,
91
+ // it's possible that this callback will be invoked for a stale (previous) subscription.
92
+ // This check avoids scheduling an update for that stale subscription.
93
+ if (
94
+ prevState.getCurrentValue !== getCurrentValue ||
95
+ prevState.subscribe !== subscribe
96
+ ) {
97
+ return prevState;
98
}
99
83
- // We use a state updater function to avoid scheduling work for a stale source.
84
- // However it's important to eagerly read the currently value,
85
- // so that all scheduled work shares the same value (in the event of multiple subscriptions).
86
- // This avoids visual "tearing" when a mutation happens during a (concurrent) render.
87
- const value = getCurrentValue();
88
-
89
- setState(prevState => {
90
- // Ignore values from stale sources!
91
- // Since we subscribe an unsubscribe in a passive effect,
92
- // it's possible that this callback will be invoked for a stale (previous) subscription.
93
- // This check avoids scheduling an update for that stale subscription.
94
- if (
95
- prevState.getCurrentValue !== getCurrentValue ||
96
- prevState.subscribe !== subscribe
97
- ) {
98
- return prevState;
99
- }
100
-
101
- // Some subscriptions will auto-invoke the handler, even if the value hasn't changed.
102
- // If the value hasn't changed, no update is needed.
103
- // Return state as-is so React can bail out and avoid an unnecessary render.
104
- if (prevState.value === value) {
105
- return prevState;
106
- }
107
-
108
- return {...prevState, value};
109
- });
110
- };
111
- const unsubscribe = subscribe(checkForUpdates);
112
-
113
- // Because we're subscribing in a passive effect,
114
- // it's possible that an update has occurred between render and our effect handler.
115
- // Check for this and schedule an update if work has occurred.
116
- checkForUpdates();
117
-
118
- return () => {
119
- didUnsubscribe = true;
120
- unsubscribe();
121
- };
122
- },
123
- [getCurrentValue, subscribe],
124
- );
100
+ // Some subscriptions will auto-invoke the handler, even if the value hasn't changed.
101
+ // If the value hasn't changed, no update is needed.
102
+ // Return state as-is so React can bail out and avoid an unnecessary render.
103
+ if (prevState.value === value) {
104
+ return prevState;
105
+ }
106
+
107
+ return {...prevState, value};
108
+ });
109
+ };
110
+ const unsubscribe = subscribe(checkForUpdates);
111
+
112
+ // Because we're subscribing in a passive effect,
113
+ // it's possible that an update has occurred between render and our effect handler.
114
+ // Check for this and schedule an update if work has occurred.
115
+ checkForUpdates();
116
+
117
+ return () => {
118
+ didUnsubscribe = true;
119
+ unsubscribe();
120
+ };
121
+ }, [getCurrentValue, subscribe]);
122
123
// Return the current value for our caller to use while rendering.
124
return valueToReturn;
scripts/jest/matchers/interactionTracingMatchers.js
+1
-3
@@ -77,9 +77,7 @@ function toMatchInteractions(actualSetOrArray, expectedSetOrArray) {
77
if (actualArray.length !== expectedArray.length) {
78
return {
79
message: () =>
80
- `Expected ${expectedArray.length} interactions but there were ${
81
- actualArray.length
82
- }`,
80
+ `Expected ${expectedArray.length} interactions but there were ${actualArray.length}`,
81
pass: false,
82
};
83
}
scripts/jest/matchers/profilerMatchers.js
+1
-3
@@ -51,9 +51,7 @@ function toMatchInteractions(actualSetOrArray, expectedSetOrArray) {
51
if (actualArray.length !== expectedArray.length) {
52
return {
53
message: () =>
54
- `Expected ${expectedArray.length} interactions but there were ${
55
- actualArray.length
56
- }`,
54
+ `Expected ${expectedArray.length} interactions but there were ${actualArray.length}`,
55
pass: false,
56
};
57
}
scripts/jest/matchers/toWarnDev.js
+1
-3
@@ -177,9 +177,7 @@ const createMatcherFor = (consoleMethod, matcherName) =>
177
if (withoutStack !== warningsWithoutComponentStack.length) {
178
return {
179
message: () =>
180
- `Expected ${withoutStack} warnings without a component stack but received ${
181
- warningsWithoutComponentStack.length
182
- }:\n` +
180
+ `Expected ${withoutStack} warnings without a component stack but received ${warningsWithoutComponentStack.length}:\n` +
181
warningsWithoutComponentStack.map(warning =>
182
this.utils.printReceived(warning)
183
),
scripts/jest/setupHostConfigs.js
+6
-18
@@ -57,9 +57,7 @@ inlinedHostConfigs.forEach(rendererInfo => {
57
jest.mock(shimHostConfigPath, () => {
58
hasImportedShimmedConfig = true;
59
return require.requireActual(
60
- `react-reconciler/src/forks/ReactFiberHostConfig.${
61
- rendererInfo.shortName
62
- }.js`
60
+ `react-reconciler/src/forks/ReactFiberHostConfig.${rendererInfo.shortName}.js`
61
);
62
});
63
@@ -88,17 +86,13 @@ inlinedHostConfigs.forEach(rendererInfo => {
86
jest.mock(shimServerHostConfigPath, () => {
87
hasImportedShimmedConfig = true;
88
return require.requireActual(
91
- `react-server/src/forks/ReactServerHostConfig.${
92
- rendererInfo.shortName
93
- }.js`
89
+ `react-server/src/forks/ReactServerHostConfig.${rendererInfo.shortName}.js`
90
);
91
});
92
jest.mock(shimServerFormatConfigPath, () => {
93
hasImportedShimmedConfig = true;
94
return require.requireActual(
99
- `react-server/src/forks/ReactServerFormatConfig.${
100
- rendererInfo.shortName
101
- }.js`
95
+ `react-server/src/forks/ReactServerFormatConfig.${rendererInfo.shortName}.js`
96
);
97
});
98
@@ -126,17 +120,13 @@ inlinedHostConfigs.forEach(rendererInfo => {
120
jest.mock(shimServerHostConfigPath, () => {
121
hasImportedShimmedConfig = true;
122
return require.requireActual(
129
- `react-server/src/forks/ReactServerHostConfig.${
130
- rendererInfo.shortName
131
- }.js`
123
+ `react-server/src/forks/ReactServerHostConfig.${rendererInfo.shortName}.js`
124
);
125
});
126
jest.mock(shimServerFormatConfigPath, () => {
127
hasImportedShimmedConfig = true;
128
return require.requireActual(
137
- `react-server/src/forks/ReactServerFormatConfig.${
138
- rendererInfo.shortName
139
- }.js`
129
+ `react-server/src/forks/ReactServerFormatConfig.${rendererInfo.shortName}.js`
130
);
131
});
132
@@ -164,9 +154,7 @@ inlinedHostConfigs.forEach(rendererInfo => {
154
jest.mock(shimFlightClientHostConfigPath, () => {
155
hasImportedShimmedConfig = true;
156
return require.requireActual(
167
- `react-flight/src/forks/ReactFlightClientHostConfig.${
168
- rendererInfo.shortName
169
- }.js`
157
+ `react-flight/src/forks/ReactFlightClientHostConfig.${rendererInfo.shortName}.js`
158
);
159
});
160
scripts/release/create-canary-commands/copy-repo-to-temp-directory.js
+1
-3
@@ -27,8 +27,6 @@ const run = async ({commit, cwd, tempDirectory}) => {
27
module.exports = async params => {
28
return logPromise(
29
run(params),
30
- theme`Copying React repo to temporary directory ({path ${
31
- params.tempDirectory
32
- }})`
30
+ theme`Copying React repo to temporary directory ({path ${params.tempDirectory}})`
31
);
32
};
scripts/release/create-canary-commands/npm-pack-and-unpack.js
+2
-6
@@ -32,18 +32,14 @@ const run = async ({cwd, dry, tempDirectory}) => {
32
const compressedPackages = readdirSync(join(cwd, 'build/node_modules/'));
33
for (let i = 0; i < compressedPackages.length; i++) {
34
await exec(
35
- `tar -zxvf ./build/node_modules/${
36
- compressedPackages[i]
37
- } -C ./build/node_modules/`,
35
+ `tar -zxvf ./build/node_modules/${compressedPackages[i]} -C ./build/node_modules/`,
36
{cwd}
37
);
38
const packageJSON = readJsonSync(
39
join(cwd, `./build/node_modules/package/package.json`)
40
);
41
await exec(
44
- `mv ./build/node_modules/package ./build/node_modules/${
45
- packageJSON.name
46
- }`,
42
+ `mv ./build/node_modules/package ./build/node_modules/${packageJSON.name}`,
43
{cwd}
44
);
45
}
scripts/release/prepare-stable-commands/update-stable-version-numbers.js
+1
-3
@@ -90,9 +90,7 @@ const run = async ({cwd, packages, version}, versionsMap) => {
90
for (let dependencyName in maybeDependency) {
91
if (packages.includes(dependencyName)) {
92
console.log(
93
- theme`• {package ${dependencyName}} {version ${
94
- maybeDependency[dependencyName]
95
- }} {dimmed ${label}}`
93
+ theme`• {package ${dependencyName}} {version ${maybeDependency[dependencyName]}} {dimmed ${label}}`
94
);
95
}
96
}
scripts/release/publish-commands/publish-to-npm.js
+2
-6
@@ -44,17 +44,13 @@ const run = async ({cwd, dry, packages, tags}, otp) => {
44
for (let j = 1; j < tags.length; j++) {
45
if (!dry) {
46
await exec(
47
- `npm dist-tag add ${packageName}@${version} ${
48
- tags[j]
49
- } --otp=${otp}`,
47
+ `npm dist-tag add ${packageName}@${version} ${tags[j]} --otp=${otp}`,
48
{cwd: packagePath}
49
);
50
}
51
console.log(
52
theme.command(
55
- ` npm dist-tag add ${packageName}@${version} ${
56
- tags[j]
57
- } --otp=${otp}`
53
+ ` npm dist-tag add ${packageName}@${version} ${tags[j]} --otp=${otp}`
54
)
55
);
56
}
scripts/release/shared-commands/download-build-artifacts.js
+2
-6
@@ -40,18 +40,14 @@ const run = async ({build, cwd}) => {
40
const compressedPackages = readdirSync(join(cwd, 'build/node_modules/'));
41
for (let i = 0; i < compressedPackages.length; i++) {
42
await exec(
43
- `tar zxvf ./build/node_modules/${
44
- compressedPackages[i]
45
- } -C ./build/node_modules/`,
43
+ `tar zxvf ./build/node_modules/${compressedPackages[i]} -C ./build/node_modules/`,
44
{cwd}
45
);
46
const packageJSON = readJsonSync(
47
join(cwd, `/build/node_modules/package/package.json`)
48
);
49
await exec(
52
- `mv ./build/node_modules/package ./build/node_modules/${
53
- packageJSON.name
54
- }`,
50
+ `mv ./build/node_modules/package ./build/node_modules/${packageJSON.name}`,
51
{cwd}
52
);
53
}
scripts/release/utils.js
+3
-9
@@ -41,9 +41,7 @@ const execRead = async (command, options) => {
41
};
42
43
const getArtifactsList = async buildID => {
44
- const buildMetadataURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${buildID}?circle-token=${
45
- process.env.CIRCLE_CI_API_TOKEN
46
- }`;
44
+ const buildMetadataURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${buildID}?circle-token=${process.env.CIRCLE_CI_API_TOKEN}`;
45
const buildMetadata = await http.get(buildMetadataURL, true);
46
if (!buildMetadata.workflows || !buildMetadata.workflows.workflow_id) {
47
console.log(
@@ -57,9 +55,7 @@ const getArtifactsList = async buildID => {
55
? 'process_artifacts_experimental'
56
: 'process_artifacts';
57
const workflowID = buildMetadata.workflows.workflow_id;
60
- const workflowMetadataURL = `https://circleci.com/api/v2/workflow/${workflowID}/job?circle-token=${
61
- process.env.CIRCLE_CI_API_TOKEN
62
- }`;
58
+ const workflowMetadataURL = `https://circleci.com/api/v2/workflow/${workflowID}/job?circle-token=${process.env.CIRCLE_CI_API_TOKEN}`;
59
const workflowMetadata = await http.get(workflowMetadataURL, true);
60
const job = workflowMetadata.items.find(
61
({name}) => name === artifactsJobName
@@ -71,9 +67,7 @@ const getArtifactsList = async buildID => {
67
process.exit(1);
68
}
69
74
- const jobArtifactsURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${
75
- job.job_number
76
- }/artifacts?circle-token=${process.env.CIRCLE_CI_API_TOKEN}`;
70
+ const jobArtifactsURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${job.job_number}/artifacts?circle-token=${process.env.CIRCLE_CI_API_TOKEN}`;
71
const jobArtifacts = await http.get(jobArtifactsURL, true);
72
73
return jobArtifacts;
scripts/rollup/forks.js
+4
-12
@@ -278,9 +278,7 @@ const forks = Object.freeze({
278
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
279
for (let rendererInfo of inlinedHostConfigs) {
280
if (rendererInfo.entryPoints.indexOf(entry) !== -1) {
281
- return `react-reconciler/src/forks/ReactFiberHostConfig.${
282
- rendererInfo.shortName
283
- }.js`;
281
+ return `react-reconciler/src/forks/ReactFiberHostConfig.${rendererInfo.shortName}.js`;
282
}
283
}
284
throw new Error(
@@ -308,9 +306,7 @@ const forks = Object.freeze({
306
if (!rendererInfo.isServerSupported) {
307
return null;
308
}
311
- return `react-server/src/forks/ReactServerHostConfig.${
312
- rendererInfo.shortName
313
- }.js`;
309
+ return `react-server/src/forks/ReactServerHostConfig.${rendererInfo.shortName}.js`;
310
}
311
}
312
throw new Error(
@@ -338,9 +334,7 @@ const forks = Object.freeze({
334
if (!rendererInfo.isServerSupported) {
335
return null;
336
}
341
- return `react-server/src/forks/ReactServerFormatConfig.${
342
- rendererInfo.shortName
343
- }.js`;
337
+ return `react-server/src/forks/ReactServerFormatConfig.${rendererInfo.shortName}.js`;
338
}
339
}
340
throw new Error(
@@ -368,9 +362,7 @@ const forks = Object.freeze({
362
if (!rendererInfo.isServerSupported) {
363
return null;
364
}
371
- return `react-flight/src/forks/ReactFlightClientHostConfig.${
372
- rendererInfo.shortName
373
- }.js`;
365
+ return `react-flight/src/forks/ReactFlightClientHostConfig.${rendererInfo.shortName}.js`;
366
}
367
}
368
throw new Error(
scripts/rollup/packaging.js
+3
-3
@@ -135,9 +135,9 @@ async function prepareNpmPackage(name) {
135
),
136
asyncCopyTo(`packages/${name}/npm`, `build/node_modules/${name}`),
137
]);
138
- const tgzName = (await asyncExecuteCommand(
139
- `npm pack build/node_modules/${name}`
140
- )).trim();
138
+ const tgzName = (
139
+ await asyncExecuteCommand(`npm pack build/node_modules/${name}`)
140
+ ).trim();
141
await asyncRimRaf(`build/node_modules/${name}`);
142
await asyncExtractTar(getTarOptions(tgzName, name));
143
unlinkSync(tgzName);
scripts/rollup/wrappers.js
+24
-24
@@ -71,14 +71,14 @@ ${license}
71
'use strict';
72
73
${
74
- globalName === 'ReactNoopRenderer' ||
75
- globalName === 'ReactNoopRendererPersistent'
76
- ? // React Noop needs regenerator runtime because it uses
77
- // generators but GCC doesn't handle them in the output.
78
- // So we use Babel for them.
79
- `const regeneratorRuntime = require("regenerator-runtime");`
80
- : ``
81
- }
74
+ globalName === 'ReactNoopRenderer' ||
75
+ globalName === 'ReactNoopRendererPersistent'
76
+ ? // React Noop needs regenerator runtime because it uses
77
+ // generators but GCC doesn't handle them in the output.
78
+ // So we use Babel for them.
79
+ `const regeneratorRuntime = require("regenerator-runtime");`
80
+ : ``
81
+}
82
83
if (process.env.NODE_ENV !== "production") {
84
(function() {
@@ -95,14 +95,14 @@ ${source}
95
${license}
96
*/
97
${
98
- globalName === 'ReactNoopRenderer' ||
99
- globalName === 'ReactNoopRendererPersistent'
100
- ? // React Noop needs regenerator runtime because it uses
101
- // generators but GCC doesn't handle them in the output.
102
- // So we use Babel for them.
103
- `const regeneratorRuntime = require("regenerator-runtime");`
104
- : ``
105
- }
98
+ globalName === 'ReactNoopRenderer' ||
99
+ globalName === 'ReactNoopRendererPersistent'
100
+ ? // React Noop needs regenerator runtime because it uses
101
+ // generators but GCC doesn't handle them in the output.
102
+ // So we use Babel for them.
103
+ `const regeneratorRuntime = require("regenerator-runtime");`
104
+ : ``
105
+}
106
${source}`;
107
},
108
@@ -114,14 +114,14 @@ ${source}`;
114
${license}
115
*/
116
${
117
- globalName === 'ReactNoopRenderer' ||
118
- globalName === 'ReactNoopRendererPersistent'
119
- ? // React Noop needs regenerator runtime because it uses
120
- // generators but GCC doesn't handle them in the output.
121
- // So we use Babel for them.
122
- `const regeneratorRuntime = require("regenerator-runtime");`
123
- : ``
124
- }
117
+ globalName === 'ReactNoopRenderer' ||
118
+ globalName === 'ReactNoopRendererPersistent'
119
+ ? // React Noop needs regenerator runtime because it uses
120
+ // generators but GCC doesn't handle them in the output.
121
+ // So we use Babel for them.
122
+ `const regeneratorRuntime = require("regenerator-runtime");`
123
+ : ``
124
+}
125
${source}`;
126
},
127
yarn.lock
+7
-1
@@ -4864,6 +4864,7 @@ eslint-plugin-no-unsafe-innerhtml@1.0.16:
4864
4865
"eslint-plugin-react-internal@link:./scripts/eslint-rules":
4866
version "0.0.0"
4867
+ uid ""
4868
4869
eslint-plugin-react@^6.7.1:
4870
version "6.10.3"
@@ -10059,7 +10060,12 @@ preserve@^0.2.0:
10060
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
10061
integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=
10062
10062
-prettier@1.13.7, prettier@^1.0.0:
10063
+prettier@1.19.1:
10064
+ version "1.19.1"
10065
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
10066
+ integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
10067
+
10068
+prettier@^1.0.0:
10069
version "1.13.7"
10070
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.7.tgz#850f3b8af784a49a6ea2d2eaa7ed1428a34b7281"
10071
integrity sha512-KIU72UmYPGk4MujZGYMFwinB7lOf2LsDNGSOC8ufevsrPLISrZbNJlWstRi3m0AMuszbH+EFSQ/r6w56RSPK6w==