Flip tuple order of useTransition (#20976)
Ricky committed
Apr 20, 2021 at 12:21 UTC
a632f7de3bd35eaf6d5082054af4da92dd37cf20
15 files changed
+58
-61
packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
+4
-4
@@ -604,10 +604,10 @@ const tests = {
604
const [state4, dispatch2] = React.useReducer();
605
const [state5, maybeSetState] = useFunnyState();
606
const [state6, maybeDispatch] = useFunnyReducer();
607
- const [startTransition1] = useTransition();
608
- const [startTransition2, isPending2] = useTransition();
609
- const [startTransition3] = React.useTransition();
610
- const [startTransition4, isPending4] = React.useTransition();
607
+ const [isPending1] = useTransition();
608
+ const [isPending2, startTransition2] = useTransition();
609
+ const [isPending3] = React.useTransition();
610
+ const [isPending4, startTransition4] = React.useTransition();
611
const mySetState = useCallback(() => {}, []);
612
let myDispatch = useCallback(() => {}, []);
613
packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
+8
-3
@@ -255,9 +255,14 @@ export default {
255
}
256
}
257
} else if (name === 'useTransition') {
258
- if (id.type === 'ArrayPattern' && isArray(resolved.identifiers)) {
259
- // Is first tuple value the same reference we're checking?
260
- if (id.elements[0] === resolved.identifiers[0]) {
258
+ // Only consider second value in initializing tuple stable.
259
+ if (
260
+ id.type === 'ArrayPattern' &&
261
+ id.elements.length === 2 &&
262
+ Array.isArray(resolved.identifiers)
263
+ ) {
264
+ // Is second tuple value the same reference we're checking?
265
+ if (id.elements[1] === resolved.identifiers[0]) {
266
// Setter is stable.
267
return true;
268
}
packages/react-debug-tools/src/ReactDebugHooks.js
+2
-2
@@ -265,7 +265,7 @@ function useMutableSource<Source, Snapshot>(
265
return value;
266
}
267
268
-function useTransition(): [(() => void) => void, boolean] {
268
+function useTransition(): [boolean, (() => void) => void] {
269
// useTransition() composes multiple hooks internally.
270
// Advance the current hook index the same number of times
271
// so that subsequent hooks have the right memoized state.
@@ -276,7 +276,7 @@ function useTransition(): [(() => void) => void, boolean] {
276
stackError: new Error(),
277
value: undefined,
278
});
279
- return [callback => {}, false];
279
+ return [false, callback => {}];
280
}
281
282
function useDeferredValue<T>(value: T): T {
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementErrorsAndWarningsTree.js
+2
-2
@@ -41,8 +41,8 @@ export default function InspectedElementErrorsAndWarningsTree({
41
const refresh = useCacheRefresh();
42
43
const [
44
- startClearErrorsTransition,
44
isErrorsTransitionPending,
45
+ startClearErrorsTransition,
46
] = useTransition();
47
const clearErrorsForInspectedElement = () => {
48
const {id} = inspectedElement;
@@ -60,8 +60,8 @@ export default function InspectedElementErrorsAndWarningsTree({
60
};
61
62
const [
63
- startClearWarningsTransition,
63
isWarningsTransitionPending,
64
+ startClearWarningsTransition,
65
] = useTransition();
66
const clearWarningsForInspectedElement = () => {
67
const {id} = inspectedElement;
packages/react-devtools-shared/src/devtools/views/Components/KeyValue.js
+1
-1
@@ -90,7 +90,7 @@ export default function KeyValue({
90
isReadOnly = value[meta.readonly];
91
}
92
93
- const [startInspectPathsTransition, isInspectPathsPending] = useTransition();
93
+ const [isInspectPathsPending, startInspectPathsTransition] = useTransition();
94
const toggleIsOpen = () => {
95
if (isOpen) {
96
setIsOpen(false);
packages/react-dom/src/server/ReactPartialRendererHooks.js
+2
-2
@@ -467,12 +467,12 @@ function useDeferredValue<T>(value: T): T {
467
return value;
468
}
469
470
-function useTransition(): [(callback: () => void) => void, boolean] {
470
+function useTransition(): [boolean, (callback: () => void) => void] {
471
resolveCurrentlyRenderingComponent();
472
const startTransition = callback => {
473
callback();
474
};
475
- return [startTransition, false];
475
+ return [false, startTransition];
476
}
477
478
function useOpaqueIdentifier(): OpaqueIDType {
packages/react-reconciler/src/ReactFiberHooks.new.js
+13
-13
@@ -1723,27 +1723,27 @@ function startTransition(setPending, callback) {
1723
}
1724
}
1725
1726
-function mountTransition(): [(() => void) => void, boolean] {
1726
+function mountTransition(): [boolean, (() => void) => void] {
1727
const [isPending, setPending] = mountState(false);
1728
// The `start` method never changes.
1729
const start = startTransition.bind(null, setPending);
1730
const hook = mountWorkInProgressHook();
1731
hook.memoizedState = start;
1732
- return [start, isPending];
1732
+ return [isPending, start];
1733
}
1734
1735
-function updateTransition(): [(() => void) => void, boolean] {
1735
+function updateTransition(): [boolean, (() => void) => void] {
1736
const [isPending] = updateState(false);
1737
const hook = updateWorkInProgressHook();
1738
const start = hook.memoizedState;
1739
- return [start, isPending];
1739
+ return [isPending, start];
1740
}
1741
1742
-function rerenderTransition(): [(() => void) => void, boolean] {
1742
+function rerenderTransition(): [boolean, (() => void) => void] {
1743
const [isPending] = rerenderState(false);
1744
const hook = updateWorkInProgressHook();
1745
const start = hook.memoizedState;
1746
- return [start, isPending];
1746
+ return [isPending, start];
1747
}
1748
1749
let isUpdatingOpaqueValueInRenderPhase = false;
@@ -2283,7 +2283,7 @@ if (__DEV__) {
2283
mountHookTypesDev();
2284
return mountDeferredValue(value);
2285
},
2286
- useTransition(): [(() => void) => void, boolean] {
2286
+ useTransition(): [boolean, (() => void) => void] {
2287
currentHookNameInDev = 'useTransition';
2288
mountHookTypesDev();
2289
return mountTransition();
@@ -2407,7 +2407,7 @@ if (__DEV__) {
2407
updateHookTypesDev();
2408
return mountDeferredValue(value);
2409
},
2410
- useTransition(): [(() => void) => void, boolean] {
2410
+ useTransition(): [boolean, (() => void) => void] {
2411
currentHookNameInDev = 'useTransition';
2412
updateHookTypesDev();
2413
return mountTransition();
@@ -2531,7 +2531,7 @@ if (__DEV__) {
2531
updateHookTypesDev();
2532
return updateDeferredValue(value);
2533
},
2534
- useTransition(): [(() => void) => void, boolean] {
2534
+ useTransition(): [boolean, (() => void) => void] {
2535
currentHookNameInDev = 'useTransition';
2536
updateHookTypesDev();
2537
return updateTransition();
@@ -2656,7 +2656,7 @@ if (__DEV__) {
2656
updateHookTypesDev();
2657
return rerenderDeferredValue(value);
2658
},
2659
- useTransition(): [(() => void) => void, boolean] {
2659
+ useTransition(): [boolean, (() => void) => void] {
2660
currentHookNameInDev = 'useTransition';
2661
updateHookTypesDev();
2662
return rerenderTransition();
@@ -2792,7 +2792,7 @@ if (__DEV__) {
2792
mountHookTypesDev();
2793
return mountDeferredValue(value);
2794
},
2795
- useTransition(): [(() => void) => void, boolean] {
2795
+ useTransition(): [boolean, (() => void) => void] {
2796
currentHookNameInDev = 'useTransition';
2797
warnInvalidHookAccess();
2798
mountHookTypesDev();
@@ -2931,7 +2931,7 @@ if (__DEV__) {
2931
updateHookTypesDev();
2932
return updateDeferredValue(value);
2933
},
2934
- useTransition(): [(() => void) => void, boolean] {
2934
+ useTransition(): [boolean, (() => void) => void] {
2935
currentHookNameInDev = 'useTransition';
2936
warnInvalidHookAccess();
2937
updateHookTypesDev();
@@ -3071,7 +3071,7 @@ if (__DEV__) {
3071
updateHookTypesDev();
3072
return rerenderDeferredValue(value);
3073
},
3074
- useTransition(): [(() => void) => void, boolean] {
3074
+ useTransition(): [boolean, (() => void) => void] {
3075
currentHookNameInDev = 'useTransition';
3076
warnInvalidHookAccess();
3077
updateHookTypesDev();
packages/react-reconciler/src/ReactFiberHooks.old.js
+13
-13
@@ -1723,27 +1723,27 @@ function startTransition(setPending, callback) {
1723
}
1724
}
1725
1726
-function mountTransition(): [(() => void) => void, boolean] {
1726
+function mountTransition(): [boolean, (() => void) => void] {
1727
const [isPending, setPending] = mountState(false);
1728
// The `start` method never changes.
1729
const start = startTransition.bind(null, setPending);
1730
const hook = mountWorkInProgressHook();
1731
hook.memoizedState = start;
1732
- return [start, isPending];
1732
+ return [isPending, start];
1733
}
1734
1735
-function updateTransition(): [(() => void) => void, boolean] {
1735
+function updateTransition(): [boolean, (() => void) => void] {
1736
const [isPending] = updateState(false);
1737
const hook = updateWorkInProgressHook();
1738
const start = hook.memoizedState;
1739
- return [start, isPending];
1739
+ return [isPending, start];
1740
}
1741
1742
-function rerenderTransition(): [(() => void) => void, boolean] {
1742
+function rerenderTransition(): [boolean, (() => void) => void] {
1743
const [isPending] = rerenderState(false);
1744
const hook = updateWorkInProgressHook();
1745
const start = hook.memoizedState;
1746
- return [start, isPending];
1746
+ return [isPending, start];
1747
}
1748
1749
let isUpdatingOpaqueValueInRenderPhase = false;
@@ -2283,7 +2283,7 @@ if (__DEV__) {
2283
mountHookTypesDev();
2284
return mountDeferredValue(value);
2285
},
2286
- useTransition(): [(() => void) => void, boolean] {
2286
+ useTransition(): [boolean, (() => void) => void] {
2287
currentHookNameInDev = 'useTransition';
2288
mountHookTypesDev();
2289
return mountTransition();
@@ -2407,7 +2407,7 @@ if (__DEV__) {
2407
updateHookTypesDev();
2408
return mountDeferredValue(value);
2409
},
2410
- useTransition(): [(() => void) => void, boolean] {
2410
+ useTransition(): [boolean, (() => void) => void] {
2411
currentHookNameInDev = 'useTransition';
2412
updateHookTypesDev();
2413
return mountTransition();
@@ -2531,7 +2531,7 @@ if (__DEV__) {
2531
updateHookTypesDev();
2532
return updateDeferredValue(value);
2533
},
2534
- useTransition(): [(() => void) => void, boolean] {
2534
+ useTransition(): [boolean, (() => void) => void] {
2535
currentHookNameInDev = 'useTransition';
2536
updateHookTypesDev();
2537
return updateTransition();
@@ -2656,7 +2656,7 @@ if (__DEV__) {
2656
updateHookTypesDev();
2657
return rerenderDeferredValue(value);
2658
},
2659
- useTransition(): [(() => void) => void, boolean] {
2659
+ useTransition(): [boolean, (() => void) => void] {
2660
currentHookNameInDev = 'useTransition';
2661
updateHookTypesDev();
2662
return rerenderTransition();
@@ -2792,7 +2792,7 @@ if (__DEV__) {
2792
mountHookTypesDev();
2793
return mountDeferredValue(value);
2794
},
2795
- useTransition(): [(() => void) => void, boolean] {
2795
+ useTransition(): [boolean, (() => void) => void] {
2796
currentHookNameInDev = 'useTransition';
2797
warnInvalidHookAccess();
2798
mountHookTypesDev();
@@ -2931,7 +2931,7 @@ if (__DEV__) {
2931
updateHookTypesDev();
2932
return updateDeferredValue(value);
2933
},
2934
- useTransition(): [(() => void) => void, boolean] {
2934
+ useTransition(): [boolean, (() => void) => void] {
2935
currentHookNameInDev = 'useTransition';
2936
warnInvalidHookAccess();
2937
updateHookTypesDev();
@@ -3071,7 +3071,7 @@ if (__DEV__) {
3071
updateHookTypesDev();
3072
return rerenderDeferredValue(value);
3073
},
3074
- useTransition(): [(() => void) => void, boolean] {
3074
+ useTransition(): [boolean, (() => void) => void] {
3075
currentHookNameInDev = 'useTransition';
3076
warnInvalidHookAccess();
3077
updateHookTypesDev();
packages/react-reconciler/src/ReactInternalTypes.js
+1
-1
@@ -311,7 +311,7 @@ export type Dispatcher = {|
311
): void,
312
useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void,
313
useDeferredValue<T>(value: T): T,
314
- useTransition(): [(() => void) => void, boolean],
314
+ useTransition(): [boolean, (() => void) => void],
315
useMutableSource<Source, Snapshot>(
316
source: MutableSource<Source>,
317
getSnapshot: MutableSourceGetSnapshotFn<Source, Snapshot>,
packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
+1
-1
@@ -1511,7 +1511,7 @@ describe('ReactHooks', () => {
1511
];
1512
1513
if (__EXPERIMENTAL__) {
1514
- const useTransitionHelper = () => React.useTransition({timeoutMs: 1000});
1514
+ const useTransitionHelper = () => React.useTransition();
1515
const useDeferredValueHelper = () =>
1516
React.useDeferredValue(0, {timeoutMs: 1000});
1517
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+2
-7
@@ -876,14 +876,11 @@ describe('ReactHooksWithNoopRenderer', () => {
876
// TODO: This should probably warn
877
// @gate experimental
878
it('calling startTransition inside render phase', async () => {
879
- let startTransition;
879
function App() {
880
const [counter, setCounter] = useState(0);
882
- const [_startTransition] = useTransition();
883
- startTransition = _startTransition;
881
882
if (counter === 0) {
886
- startTransition(() => {
883
+ React.unstable_startTransition(() => {
884
setCounter(c => c + 1);
885
});
886
}
@@ -3227,9 +3224,7 @@ describe('ReactHooksWithNoopRenderer', () => {
3224
let transition;
3225
function App() {
3226
const [show, setShow] = useState(false);
3230
- const [startTransition, isPending] = useTransition({
3231
- timeoutMs: 1000,
3232
- });
3227
+ const [isPending, startTransition] = useTransition();
3228
transition = () => {
3229
startTransition(() => {
3230
setShow(true);
packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
+4
-7
@@ -3745,7 +3745,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3745
let startTransition;
3746
function B() {
3747
const [textB, _setTextB] = useState('B');
3748
- const [_startTransition] = useTransition({timeoutMs: 10000});
3748
+ // eslint-disable-next-line no-unused-vars
3749
+ const [_, _startTransition] = useTransition();
3750
startTransition = _startTransition;
3751
setTextB = _setTextB;
3752
return (
@@ -3843,12 +3844,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3844
let setTextWithLongTransition;
3845
3846
function App() {
3846
- const [startShortTransition, isPending1] = React.unstable_useTransition({
3847
- timeoutMs: 5000,
3848
- });
3849
- const [startLongTransition, isPending2] = React.unstable_useTransition({
3850
- timeoutMs: 30000,
3851
- });
3847
+ const [isPending1, startShortTransition] = React.unstable_useTransition();
3848
+ const [isPending2, startLongTransition] = React.unstable_useTransition();
3849
const isPending = isPending1 || isPending2;
3850
const [text, setText] = React.useState('');
3851
const [mirror, setMirror] = React.useState('');
packages/react-reconciler/src/__tests__/ReactTransition-test.js
+2
-2
@@ -164,7 +164,7 @@ describe('ReactTransition', () => {
164
let start;
165
function App() {
166
const [show, setShow] = useState(false);
167
- const [_start, isPending] = useTransition();
167
+ const [isPending, _start] = useTransition();
168
start = () => _start(() => setShow(true));
169
return (
170
<Suspense fallback={<Text text="Loading..." />}>
@@ -208,7 +208,7 @@ describe('ReactTransition', () => {
208
async () => {
209
let update;
210
function App() {
211
- const [startContentChange, isContentPending] = useTransition();
211
+ const [isContentPending, startContentChange] = useTransition();
212
const [label, setLabel] = useState('A');
213
const [contents, setContents] = useState('A');
214
update = value => {
packages/react-server/src/ReactFizzHooks.js
+2
-2
@@ -470,9 +470,9 @@ function unsupportedStartTransition() {
470
invariant(false, 'startTransition cannot be called during server rendering.');
471
}
472
473
-function useTransition(): [(callback: () => void) => void, boolean] {
473
+function useTransition(): [boolean, (callback: () => void) => void] {
474
resolveCurrentlyRenderingComponent();
475
- return [unsupportedStartTransition, false];
475
+ return [false, unsupportedStartTransition];
476
}
477
478
function useOpaqueIdentifier(): OpaqueIDType {
packages/react/src/ReactHooks.js
+1
-1
@@ -145,7 +145,7 @@ export function useDebugValue<T>(
145
146
export const emptyObject = {};
147
148
-export function useTransition(): [(() => void) => void, boolean] {
148
+export function useTransition(): [boolean, (() => void) => void] {
149
const dispatcher = resolveDispatcher();
150
return dispatcher.useTransition();
151
}