Skip to content

Commit a632f7d

Browse files
authored
Flip tuple order of useTransition (#20976)
1 parent bd7f4a0 commit a632f7d

File tree

15 files changed

+58
-61
lines changed

15 files changed

+58
-61
lines changed

packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -604,10 +604,10 @@ const tests = {
604604
const [state4, dispatch2] = React.useReducer();
605605
const [state5, maybeSetState] = useFunnyState();
606606
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();
611611
const mySetState = useCallback(() => {}, []);
612612
let myDispatch = useCallback(() => {}, []);
613613

packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,14 @@ export default {
255255
}
256256
}
257257
} 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]) {
261266
// Setter is stable.
262267
return true;
263268
}

packages/react-debug-tools/src/ReactDebugHooks.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ function useMutableSource<Source, Snapshot>(
265265
return value;
266266
}
267267

268-
function useTransition(): [(() => void) => void, boolean] {
268+
function useTransition(): [boolean, (() => void) => void] {
269269
// useTransition() composes multiple hooks internally.
270270
// Advance the current hook index the same number of times
271271
// so that subsequent hooks have the right memoized state.
@@ -276,7 +276,7 @@ function useTransition(): [(() => void) => void, boolean] {
276276
stackError: new Error(),
277277
value: undefined,
278278
});
279-
return [callback => {}, false];
279+
return [false, callback => {}];
280280
}
281281

282282
function useDeferredValue<T>(value: T): T {

packages/react-devtools-shared/src/devtools/views/Components/InspectedElementErrorsAndWarningsTree.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ export default function InspectedElementErrorsAndWarningsTree({
4141
const refresh = useCacheRefresh();
4242

4343
const [
44-
startClearErrorsTransition,
4544
isErrorsTransitionPending,
45+
startClearErrorsTransition,
4646
] = useTransition();
4747
const clearErrorsForInspectedElement = () => {
4848
const {id} = inspectedElement;
@@ -60,8 +60,8 @@ export default function InspectedElementErrorsAndWarningsTree({
6060
};
6161

6262
const [
63-
startClearWarningsTransition,
6463
isWarningsTransitionPending,
64+
startClearWarningsTransition,
6565
] = useTransition();
6666
const clearWarningsForInspectedElement = () => {
6767
const {id} = inspectedElement;

packages/react-devtools-shared/src/devtools/views/Components/KeyValue.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export default function KeyValue({
9090
isReadOnly = value[meta.readonly];
9191
}
9292

93-
const [startInspectPathsTransition, isInspectPathsPending] = useTransition();
93+
const [isInspectPathsPending, startInspectPathsTransition] = useTransition();
9494
const toggleIsOpen = () => {
9595
if (isOpen) {
9696
setIsOpen(false);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,12 +467,12 @@ function useDeferredValue<T>(value: T): T {
467467
return value;
468468
}
469469

470-
function useTransition(): [(callback: () => void) => void, boolean] {
470+
function useTransition(): [boolean, (callback: () => void) => void] {
471471
resolveCurrentlyRenderingComponent();
472472
const startTransition = callback => {
473473
callback();
474474
};
475-
return [startTransition, false];
475+
return [false, startTransition];
476476
}
477477

478478
function useOpaqueIdentifier(): OpaqueIDType {

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,27 +1723,27 @@ function startTransition(setPending, callback) {
17231723
}
17241724
}
17251725

1726-
function mountTransition(): [(() => void) => void, boolean] {
1726+
function mountTransition(): [boolean, (() => void) => void] {
17271727
const [isPending, setPending] = mountState(false);
17281728
// The `start` method never changes.
17291729
const start = startTransition.bind(null, setPending);
17301730
const hook = mountWorkInProgressHook();
17311731
hook.memoizedState = start;
1732-
return [start, isPending];
1732+
return [isPending, start];
17331733
}
17341734

1735-
function updateTransition(): [(() => void) => void, boolean] {
1735+
function updateTransition(): [boolean, (() => void) => void] {
17361736
const [isPending] = updateState(false);
17371737
const hook = updateWorkInProgressHook();
17381738
const start = hook.memoizedState;
1739-
return [start, isPending];
1739+
return [isPending, start];
17401740
}
17411741

1742-
function rerenderTransition(): [(() => void) => void, boolean] {
1742+
function rerenderTransition(): [boolean, (() => void) => void] {
17431743
const [isPending] = rerenderState(false);
17441744
const hook = updateWorkInProgressHook();
17451745
const start = hook.memoizedState;
1746-
return [start, isPending];
1746+
return [isPending, start];
17471747
}
17481748

17491749
let isUpdatingOpaqueValueInRenderPhase = false;
@@ -2283,7 +2283,7 @@ if (__DEV__) {
22832283
mountHookTypesDev();
22842284
return mountDeferredValue(value);
22852285
},
2286-
useTransition(): [(() => void) => void, boolean] {
2286+
useTransition(): [boolean, (() => void) => void] {
22872287
currentHookNameInDev = 'useTransition';
22882288
mountHookTypesDev();
22892289
return mountTransition();
@@ -2407,7 +2407,7 @@ if (__DEV__) {
24072407
updateHookTypesDev();
24082408
return mountDeferredValue(value);
24092409
},
2410-
useTransition(): [(() => void) => void, boolean] {
2410+
useTransition(): [boolean, (() => void) => void] {
24112411
currentHookNameInDev = 'useTransition';
24122412
updateHookTypesDev();
24132413
return mountTransition();
@@ -2531,7 +2531,7 @@ if (__DEV__) {
25312531
updateHookTypesDev();
25322532
return updateDeferredValue(value);
25332533
},
2534-
useTransition(): [(() => void) => void, boolean] {
2534+
useTransition(): [boolean, (() => void) => void] {
25352535
currentHookNameInDev = 'useTransition';
25362536
updateHookTypesDev();
25372537
return updateTransition();
@@ -2656,7 +2656,7 @@ if (__DEV__) {
26562656
updateHookTypesDev();
26572657
return rerenderDeferredValue(value);
26582658
},
2659-
useTransition(): [(() => void) => void, boolean] {
2659+
useTransition(): [boolean, (() => void) => void] {
26602660
currentHookNameInDev = 'useTransition';
26612661
updateHookTypesDev();
26622662
return rerenderTransition();
@@ -2792,7 +2792,7 @@ if (__DEV__) {
27922792
mountHookTypesDev();
27932793
return mountDeferredValue(value);
27942794
},
2795-
useTransition(): [(() => void) => void, boolean] {
2795+
useTransition(): [boolean, (() => void) => void] {
27962796
currentHookNameInDev = 'useTransition';
27972797
warnInvalidHookAccess();
27982798
mountHookTypesDev();
@@ -2931,7 +2931,7 @@ if (__DEV__) {
29312931
updateHookTypesDev();
29322932
return updateDeferredValue(value);
29332933
},
2934-
useTransition(): [(() => void) => void, boolean] {
2934+
useTransition(): [boolean, (() => void) => void] {
29352935
currentHookNameInDev = 'useTransition';
29362936
warnInvalidHookAccess();
29372937
updateHookTypesDev();
@@ -3071,7 +3071,7 @@ if (__DEV__) {
30713071
updateHookTypesDev();
30723072
return rerenderDeferredValue(value);
30733073
},
3074-
useTransition(): [(() => void) => void, boolean] {
3074+
useTransition(): [boolean, (() => void) => void] {
30753075
currentHookNameInDev = 'useTransition';
30763076
warnInvalidHookAccess();
30773077
updateHookTypesDev();

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,27 +1723,27 @@ function startTransition(setPending, callback) {
17231723
}
17241724
}
17251725

1726-
function mountTransition(): [(() => void) => void, boolean] {
1726+
function mountTransition(): [boolean, (() => void) => void] {
17271727
const [isPending, setPending] = mountState(false);
17281728
// The `start` method never changes.
17291729
const start = startTransition.bind(null, setPending);
17301730
const hook = mountWorkInProgressHook();
17311731
hook.memoizedState = start;
1732-
return [start, isPending];
1732+
return [isPending, start];
17331733
}
17341734

1735-
function updateTransition(): [(() => void) => void, boolean] {
1735+
function updateTransition(): [boolean, (() => void) => void] {
17361736
const [isPending] = updateState(false);
17371737
const hook = updateWorkInProgressHook();
17381738
const start = hook.memoizedState;
1739-
return [start, isPending];
1739+
return [isPending, start];
17401740
}
17411741

1742-
function rerenderTransition(): [(() => void) => void, boolean] {
1742+
function rerenderTransition(): [boolean, (() => void) => void] {
17431743
const [isPending] = rerenderState(false);
17441744
const hook = updateWorkInProgressHook();
17451745
const start = hook.memoizedState;
1746-
return [start, isPending];
1746+
return [isPending, start];
17471747
}
17481748

17491749
let isUpdatingOpaqueValueInRenderPhase = false;
@@ -2283,7 +2283,7 @@ if (__DEV__) {
22832283
mountHookTypesDev();
22842284
return mountDeferredValue(value);
22852285
},
2286-
useTransition(): [(() => void) => void, boolean] {
2286+
useTransition(): [boolean, (() => void) => void] {
22872287
currentHookNameInDev = 'useTransition';
22882288
mountHookTypesDev();
22892289
return mountTransition();
@@ -2407,7 +2407,7 @@ if (__DEV__) {
24072407
updateHookTypesDev();
24082408
return mountDeferredValue(value);
24092409
},
2410-
useTransition(): [(() => void) => void, boolean] {
2410+
useTransition(): [boolean, (() => void) => void] {
24112411
currentHookNameInDev = 'useTransition';
24122412
updateHookTypesDev();
24132413
return mountTransition();
@@ -2531,7 +2531,7 @@ if (__DEV__) {
25312531
updateHookTypesDev();
25322532
return updateDeferredValue(value);
25332533
},
2534-
useTransition(): [(() => void) => void, boolean] {
2534+
useTransition(): [boolean, (() => void) => void] {
25352535
currentHookNameInDev = 'useTransition';
25362536
updateHookTypesDev();
25372537
return updateTransition();
@@ -2656,7 +2656,7 @@ if (__DEV__) {
26562656
updateHookTypesDev();
26572657
return rerenderDeferredValue(value);
26582658
},
2659-
useTransition(): [(() => void) => void, boolean] {
2659+
useTransition(): [boolean, (() => void) => void] {
26602660
currentHookNameInDev = 'useTransition';
26612661
updateHookTypesDev();
26622662
return rerenderTransition();
@@ -2792,7 +2792,7 @@ if (__DEV__) {
27922792
mountHookTypesDev();
27932793
return mountDeferredValue(value);
27942794
},
2795-
useTransition(): [(() => void) => void, boolean] {
2795+
useTransition(): [boolean, (() => void) => void] {
27962796
currentHookNameInDev = 'useTransition';
27972797
warnInvalidHookAccess();
27982798
mountHookTypesDev();
@@ -2931,7 +2931,7 @@ if (__DEV__) {
29312931
updateHookTypesDev();
29322932
return updateDeferredValue(value);
29332933
},
2934-
useTransition(): [(() => void) => void, boolean] {
2934+
useTransition(): [boolean, (() => void) => void] {
29352935
currentHookNameInDev = 'useTransition';
29362936
warnInvalidHookAccess();
29372937
updateHookTypesDev();
@@ -3071,7 +3071,7 @@ if (__DEV__) {
30713071
updateHookTypesDev();
30723072
return rerenderDeferredValue(value);
30733073
},
3074-
useTransition(): [(() => void) => void, boolean] {
3074+
useTransition(): [boolean, (() => void) => void] {
30753075
currentHookNameInDev = 'useTransition';
30763076
warnInvalidHookAccess();
30773077
updateHookTypesDev();

packages/react-reconciler/src/ReactInternalTypes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ export type Dispatcher = {|
311311
): void,
312312
useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void,
313313
useDeferredValue<T>(value: T): T,
314-
useTransition(): [(() => void) => void, boolean],
314+
useTransition(): [boolean, (() => void) => void],
315315
useMutableSource<Source, Snapshot>(
316316
source: MutableSource<Source>,
317317
getSnapshot: MutableSourceGetSnapshotFn<Source, Snapshot>,

packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1511,7 +1511,7 @@ describe('ReactHooks', () => {
15111511
];
15121512

15131513
if (__EXPERIMENTAL__) {
1514-
const useTransitionHelper = () => React.useTransition({timeoutMs: 1000});
1514+
const useTransitionHelper = () => React.useTransition();
15151515
const useDeferredValueHelper = () =>
15161516
React.useDeferredValue(0, {timeoutMs: 1000});
15171517

packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -876,14 +876,11 @@ describe('ReactHooksWithNoopRenderer', () => {
876876
// TODO: This should probably warn
877877
// @gate experimental
878878
it('calling startTransition inside render phase', async () => {
879-
let startTransition;
880879
function App() {
881880
const [counter, setCounter] = useState(0);
882-
const [_startTransition] = useTransition();
883-
startTransition = _startTransition;
884881

885882
if (counter === 0) {
886-
startTransition(() => {
883+
React.unstable_startTransition(() => {
887884
setCounter(c => c + 1);
888885
});
889886
}
@@ -3227,9 +3224,7 @@ describe('ReactHooksWithNoopRenderer', () => {
32273224
let transition;
32283225
function App() {
32293226
const [show, setShow] = useState(false);
3230-
const [startTransition, isPending] = useTransition({
3231-
timeoutMs: 1000,
3232-
});
3227+
const [isPending, startTransition] = useTransition();
32333228
transition = () => {
32343229
startTransition(() => {
32353230
setShow(true);

packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3745,7 +3745,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
37453745
let startTransition;
37463746
function B() {
37473747
const [textB, _setTextB] = useState('B');
3748-
const [_startTransition] = useTransition({timeoutMs: 10000});
3748+
// eslint-disable-next-line no-unused-vars
3749+
const [_, _startTransition] = useTransition();
37493750
startTransition = _startTransition;
37503751
setTextB = _setTextB;
37513752
return (
@@ -3843,12 +3844,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
38433844
let setTextWithLongTransition;
38443845

38453846
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();
38523849
const isPending = isPending1 || isPending2;
38533850
const [text, setText] = React.useState('');
38543851
const [mirror, setMirror] = React.useState('');

packages/react-reconciler/src/__tests__/ReactTransition-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ describe('ReactTransition', () => {
164164
let start;
165165
function App() {
166166
const [show, setShow] = useState(false);
167-
const [_start, isPending] = useTransition();
167+
const [isPending, _start] = useTransition();
168168
start = () => _start(() => setShow(true));
169169
return (
170170
<Suspense fallback={<Text text="Loading..." />}>
@@ -208,7 +208,7 @@ describe('ReactTransition', () => {
208208
async () => {
209209
let update;
210210
function App() {
211-
const [startContentChange, isContentPending] = useTransition();
211+
const [isContentPending, startContentChange] = useTransition();
212212
const [label, setLabel] = useState('A');
213213
const [contents, setContents] = useState('A');
214214
update = value => {

packages/react-server/src/ReactFizzHooks.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,9 +470,9 @@ function unsupportedStartTransition() {
470470
invariant(false, 'startTransition cannot be called during server rendering.');
471471
}
472472

473-
function useTransition(): [(callback: () => void) => void, boolean] {
473+
function useTransition(): [boolean, (callback: () => void) => void] {
474474
resolveCurrentlyRenderingComponent();
475-
return [unsupportedStartTransition, false];
475+
return [false, unsupportedStartTransition];
476476
}
477477

478478
function useOpaqueIdentifier(): OpaqueIDType {

packages/react/src/ReactHooks.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export function useDebugValue<T>(
145145

146146
export const emptyObject = {};
147147

148-
export function useTransition(): [(() => void) => void, boolean] {
148+
export function useTransition(): [boolean, (() => void) => void] {
149149
const dispatcher = resolveDispatcher();
150150
return dispatcher.useTransition();
151151
}

0 commit comments

Comments
 (0)