Skip to content

Commit

Permalink
Flip tuple order of useTransition (facebook#20976)
Browse files Browse the repository at this point in the history
  • Loading branch information
rickhanlonii authored and koto committed Jun 15, 2021
1 parent 4bd4eb9 commit c711806
Show file tree
Hide file tree
Showing 15 changed files with 58 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -604,10 +604,10 @@ const tests = {
const [state4, dispatch2] = React.useReducer();
const [state5, maybeSetState] = useFunnyState();
const [state6, maybeDispatch] = useFunnyReducer();
const [startTransition1] = useTransition();
const [startTransition2, isPending2] = useTransition();
const [startTransition3] = React.useTransition();
const [startTransition4, isPending4] = React.useTransition();
const [isPending1] = useTransition();
const [isPending2, startTransition2] = useTransition();
const [isPending3] = React.useTransition();
const [isPending4, startTransition4] = React.useTransition();
const mySetState = useCallback(() => {}, []);
let myDispatch = useCallback(() => {}, []);
Expand Down
11 changes: 8 additions & 3 deletions packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,14 @@ export default {
}
}
} else if (name === 'useTransition') {
if (id.type === 'ArrayPattern' && isArray(resolved.identifiers)) {
// Is first tuple value the same reference we're checking?
if (id.elements[0] === resolved.identifiers[0]) {
// Only consider second value in initializing tuple stable.
if (
id.type === 'ArrayPattern' &&
id.elements.length === 2 &&
Array.isArray(resolved.identifiers)
) {
// Is second tuple value the same reference we're checking?
if (id.elements[1] === resolved.identifiers[0]) {
// Setter is stable.
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/react-debug-tools/src/ReactDebugHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ function useMutableSource<Source, Snapshot>(
return value;
}

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

function useDeferredValue<T>(value: T): T {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export default function InspectedElementErrorsAndWarningsTree({
const refresh = useCacheRefresh();

const [
startClearErrorsTransition,
isErrorsTransitionPending,
startClearErrorsTransition,
] = useTransition();
const clearErrorsForInspectedElement = () => {
const {id} = inspectedElement;
Expand All @@ -60,8 +60,8 @@ export default function InspectedElementErrorsAndWarningsTree({
};

const [
startClearWarningsTransition,
isWarningsTransitionPending,
startClearWarningsTransition,
] = useTransition();
const clearWarningsForInspectedElement = () => {
const {id} = inspectedElement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export default function KeyValue({
isReadOnly = value[meta.readonly];
}

const [startInspectPathsTransition, isInspectPathsPending] = useTransition();
const [isInspectPathsPending, startInspectPathsTransition] = useTransition();
const toggleIsOpen = () => {
if (isOpen) {
setIsOpen(false);
Expand Down
4 changes: 2 additions & 2 deletions packages/react-dom/src/server/ReactPartialRendererHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,12 +467,12 @@ function useDeferredValue<T>(value: T): T {
return value;
}

function useTransition(): [(callback: () => void) => void, boolean] {
function useTransition(): [boolean, (callback: () => void) => void] {
resolveCurrentlyRenderingComponent();
const startTransition = callback => {
callback();
};
return [startTransition, false];
return [false, startTransition];
}

function useOpaqueIdentifier(): OpaqueIDType {
Expand Down
26 changes: 13 additions & 13 deletions packages/react-reconciler/src/ReactFiberHooks.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -1723,27 +1723,27 @@ function startTransition(setPending, callback) {
}
}

function mountTransition(): [(() => void) => void, boolean] {
function mountTransition(): [boolean, (() => void) => void] {
const [isPending, setPending] = mountState(false);
// The `start` method never changes.
const start = startTransition.bind(null, setPending);
const hook = mountWorkInProgressHook();
hook.memoizedState = start;
return [start, isPending];
return [isPending, start];
}

function updateTransition(): [(() => void) => void, boolean] {
function updateTransition(): [boolean, (() => void) => void] {
const [isPending] = updateState(false);
const hook = updateWorkInProgressHook();
const start = hook.memoizedState;
return [start, isPending];
return [isPending, start];
}

function rerenderTransition(): [(() => void) => void, boolean] {
function rerenderTransition(): [boolean, (() => void) => void] {
const [isPending] = rerenderState(false);
const hook = updateWorkInProgressHook();
const start = hook.memoizedState;
return [start, isPending];
return [isPending, start];
}

let isUpdatingOpaqueValueInRenderPhase = false;
Expand Down Expand Up @@ -2283,7 +2283,7 @@ if (__DEV__) {
mountHookTypesDev();
return mountDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
mountHookTypesDev();
return mountTransition();
Expand Down Expand Up @@ -2407,7 +2407,7 @@ if (__DEV__) {
updateHookTypesDev();
return mountDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return mountTransition();
Expand Down Expand Up @@ -2531,7 +2531,7 @@ if (__DEV__) {
updateHookTypesDev();
return updateDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return updateTransition();
Expand Down Expand Up @@ -2656,7 +2656,7 @@ if (__DEV__) {
updateHookTypesDev();
return rerenderDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return rerenderTransition();
Expand Down Expand Up @@ -2792,7 +2792,7 @@ if (__DEV__) {
mountHookTypesDev();
return mountDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
mountHookTypesDev();
Expand Down Expand Up @@ -2931,7 +2931,7 @@ if (__DEV__) {
updateHookTypesDev();
return updateDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
updateHookTypesDev();
Expand Down Expand Up @@ -3071,7 +3071,7 @@ if (__DEV__) {
updateHookTypesDev();
return rerenderDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
updateHookTypesDev();
Expand Down
26 changes: 13 additions & 13 deletions packages/react-reconciler/src/ReactFiberHooks.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -1723,27 +1723,27 @@ function startTransition(setPending, callback) {
}
}

function mountTransition(): [(() => void) => void, boolean] {
function mountTransition(): [boolean, (() => void) => void] {
const [isPending, setPending] = mountState(false);
// The `start` method never changes.
const start = startTransition.bind(null, setPending);
const hook = mountWorkInProgressHook();
hook.memoizedState = start;
return [start, isPending];
return [isPending, start];
}

function updateTransition(): [(() => void) => void, boolean] {
function updateTransition(): [boolean, (() => void) => void] {
const [isPending] = updateState(false);
const hook = updateWorkInProgressHook();
const start = hook.memoizedState;
return [start, isPending];
return [isPending, start];
}

function rerenderTransition(): [(() => void) => void, boolean] {
function rerenderTransition(): [boolean, (() => void) => void] {
const [isPending] = rerenderState(false);
const hook = updateWorkInProgressHook();
const start = hook.memoizedState;
return [start, isPending];
return [isPending, start];
}

let isUpdatingOpaqueValueInRenderPhase = false;
Expand Down Expand Up @@ -2283,7 +2283,7 @@ if (__DEV__) {
mountHookTypesDev();
return mountDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
mountHookTypesDev();
return mountTransition();
Expand Down Expand Up @@ -2407,7 +2407,7 @@ if (__DEV__) {
updateHookTypesDev();
return mountDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return mountTransition();
Expand Down Expand Up @@ -2531,7 +2531,7 @@ if (__DEV__) {
updateHookTypesDev();
return updateDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return updateTransition();
Expand Down Expand Up @@ -2656,7 +2656,7 @@ if (__DEV__) {
updateHookTypesDev();
return rerenderDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return rerenderTransition();
Expand Down Expand Up @@ -2792,7 +2792,7 @@ if (__DEV__) {
mountHookTypesDev();
return mountDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
mountHookTypesDev();
Expand Down Expand Up @@ -2931,7 +2931,7 @@ if (__DEV__) {
updateHookTypesDev();
return updateDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
updateHookTypesDev();
Expand Down Expand Up @@ -3071,7 +3071,7 @@ if (__DEV__) {
updateHookTypesDev();
return rerenderDeferredValue(value);
},
useTransition(): [(() => void) => void, boolean] {
useTransition(): [boolean, (() => void) => void] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
updateHookTypesDev();
Expand Down
2 changes: 1 addition & 1 deletion packages/react-reconciler/src/ReactInternalTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ export type Dispatcher = {|
): void,
useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void,
useDeferredValue<T>(value: T): T,
useTransition(): [(() => void) => void, boolean],
useTransition(): [boolean, (() => void) => void],
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
getSnapshot: MutableSourceGetSnapshotFn<Source, Snapshot>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1511,7 +1511,7 @@ describe('ReactHooks', () => {
];

if (__EXPERIMENTAL__) {
const useTransitionHelper = () => React.useTransition({timeoutMs: 1000});
const useTransitionHelper = () => React.useTransition();
const useDeferredValueHelper = () =>
React.useDeferredValue(0, {timeoutMs: 1000});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -876,14 +876,11 @@ describe('ReactHooksWithNoopRenderer', () => {
// TODO: This should probably warn
// @gate experimental
it('calling startTransition inside render phase', async () => {
let startTransition;
function App() {
const [counter, setCounter] = useState(0);
const [_startTransition] = useTransition();
startTransition = _startTransition;

if (counter === 0) {
startTransition(() => {
React.unstable_startTransition(() => {
setCounter(c => c + 1);
});
}
Expand Down Expand Up @@ -3227,9 +3224,7 @@ describe('ReactHooksWithNoopRenderer', () => {
let transition;
function App() {
const [show, setShow] = useState(false);
const [startTransition, isPending] = useTransition({
timeoutMs: 1000,
});
const [isPending, startTransition] = useTransition();
transition = () => {
startTransition(() => {
setShow(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3745,7 +3745,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
let startTransition;
function B() {
const [textB, _setTextB] = useState('B');
const [_startTransition] = useTransition({timeoutMs: 10000});
// eslint-disable-next-line no-unused-vars
const [_, _startTransition] = useTransition();
startTransition = _startTransition;
setTextB = _setTextB;
return (
Expand Down Expand Up @@ -3843,12 +3844,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
let setTextWithLongTransition;

function App() {
const [startShortTransition, isPending1] = React.unstable_useTransition({
timeoutMs: 5000,
});
const [startLongTransition, isPending2] = React.unstable_useTransition({
timeoutMs: 30000,
});
const [isPending1, startShortTransition] = React.unstable_useTransition();
const [isPending2, startLongTransition] = React.unstable_useTransition();
const isPending = isPending1 || isPending2;
const [text, setText] = React.useState('');
const [mirror, setMirror] = React.useState('');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ describe('ReactTransition', () => {
let start;
function App() {
const [show, setShow] = useState(false);
const [_start, isPending] = useTransition();
const [isPending, _start] = useTransition();
start = () => _start(() => setShow(true));
return (
<Suspense fallback={<Text text="Loading..." />}>
Expand Down Expand Up @@ -208,7 +208,7 @@ describe('ReactTransition', () => {
async () => {
let update;
function App() {
const [startContentChange, isContentPending] = useTransition();
const [isContentPending, startContentChange] = useTransition();
const [label, setLabel] = useState('A');
const [contents, setContents] = useState('A');
update = value => {
Expand Down
4 changes: 2 additions & 2 deletions packages/react-server/src/ReactFizzHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,9 @@ function unsupportedStartTransition() {
invariant(false, 'startTransition cannot be called during server rendering.');
}

function useTransition(): [(callback: () => void) => void, boolean] {
function useTransition(): [boolean, (callback: () => void) => void] {
resolveCurrentlyRenderingComponent();
return [unsupportedStartTransition, false];
return [false, unsupportedStartTransition];
}

function useOpaqueIdentifier(): OpaqueIDType {
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/ReactHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export function useDebugValue<T>(

export const emptyObject = {};

export function useTransition(): [(() => void) => void, boolean] {
export function useTransition(): [boolean, (() => void) => void] {
const dispatcher = resolveDispatcher();
return dispatcher.useTransition();
}
Expand Down

0 comments on commit c711806

Please sign in to comment.