Remove config argument from useTransition (#19719)

And `useDeferredValue`.

The options were already disabled in previous commits, so this doesn't
change any behavior. I upated type signatures and cleaned up the hook
implementation a bit — no longer have to wrap the `start` method with
`useCallback`, because its only remaining dependency is a `setState`
method, which never changes. Instead, we can store the `start` method
on a ref.
This commit is contained in:
Andrew Clark 2020-08-28 13:49:01 -05:00 committed by GitHub
parent 92fcd46cc7
commit ddd1faa197
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 118 additions and 223 deletions

View File

@ -20,7 +20,6 @@ import type {
} from 'react-reconciler/src/ReactInternalTypes';
import type {OpaqueIDType} from 'react-reconciler/src/ReactFiberHostConfig';
import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberTransition';
import {NoMode} from 'react-reconciler/src/ReactTypeOfMode';
import ErrorStackParser from 'error-stack-parser';
@ -62,10 +61,6 @@ type Hook = {
next: Hook | null,
};
type TimeoutConfig = {|
timeoutMs: number,
|};
function getPrimitiveStackCache(): Map<string, Array<any>> {
// This initializes a cache of all primitive hooks so that the top
// most stack frames added by calling the primitive hook can be removed.
@ -258,9 +253,7 @@ function useMutableSource<Source, Snapshot>(
return value;
}
function useTransition(
config: SuspenseConfig | null | void,
): [(() => void) => void, boolean] {
function useTransition(): [(() => void) => void, boolean] {
// useTransition() composes multiple hooks internally.
// Advance the current hook index the same number of times
// so that subsequent hooks have the right memoized state.
@ -269,12 +262,12 @@ function useTransition(
hookLog.push({
primitive: 'Transition',
stackError: new Error(),
value: config,
value: undefined,
});
return [callback => {}, false];
}
function useDeferredValue<T>(value: T, config: TimeoutConfig | null | void): T {
function useDeferredValue<T>(value: T): T {
// useDeferredValue() composes multiple hooks internally.
// Advance the current hook index the same number of times
// so that subsequent hooks have the right memoized state.

View File

@ -15,7 +15,6 @@ import type {
MutableSourceSubscribeFn,
ReactContext,
} from 'shared/ReactTypes';
import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberTransition';
import type PartialRenderer from './ReactPartialRenderer';
import {validateContextBounds} from './ReactPartialRendererContext';
@ -42,10 +41,6 @@ type Hook = {|
next: Hook | null,
|};
type TimeoutConfig = {|
timeoutMs: number,
|};
type OpaqueIDType = string;
let currentlyRenderingComponent: Object | null = null;
@ -468,14 +463,12 @@ function useMutableSource<Source, Snapshot>(
return getSnapshot(source._source);
}
function useDeferredValue<T>(value: T, config: TimeoutConfig | null | void): T {
function useDeferredValue<T>(value: T): T {
resolveCurrentlyRenderingComponent();
return value;
}
function useTransition(
config: SuspenseConfig | null | void,
): [(callback: () => void) => void, boolean] {
function useTransition(): [(callback: () => void) => void, boolean] {
resolveCurrentlyRenderingComponent();
const startTransition = callback => {
callback();

View File

@ -16,7 +16,6 @@ import type {
import type {Fiber, Dispatcher} from './ReactInternalTypes';
import type {Lanes, Lane} from './ReactFiberLane';
import type {HookEffectTag} from './ReactHookEffectTags';
import type {SuspenseConfig} from './ReactFiberTransition';
import type {ReactPriorityLevel} from './ReactInternalTypes';
import type {FiberRoot} from './ReactInternalTypes';
import type {OpaqueIDType} from './ReactFiberHostConfig';
@ -151,10 +150,6 @@ export type Effect = {|
export type FunctionComponentUpdateQueue = {|lastEffect: Effect | null|};
type TimeoutConfig = {|
timeoutMs: number,
|};
type BasicStateAction<S> = (S => S) | S;
type Dispatch<A> = A => void;
@ -1432,10 +1427,7 @@ function updateMemo<T>(
return nextValue;
}
function mountDeferredValue<T>(
value: T,
config: TimeoutConfig | void | null,
): T {
function mountDeferredValue<T>(value: T): T {
const [prevValue, setValue] = mountState(value);
mountEffect(() => {
const prevTransition = ReactCurrentBatchConfig.transition;
@ -1445,14 +1437,11 @@ function mountDeferredValue<T>(
} finally {
ReactCurrentBatchConfig.transition = prevTransition;
}
}, [value, config]);
}, [value]);
return prevValue;
}
function updateDeferredValue<T>(
value: T,
config: TimeoutConfig | void | null,
): T {
function updateDeferredValue<T>(value: T): T {
const [prevValue, setValue] = updateState(value);
updateEffect(() => {
const prevTransition = ReactCurrentBatchConfig.transition;
@ -1462,14 +1451,11 @@ function updateDeferredValue<T>(
} finally {
ReactCurrentBatchConfig.transition = prevTransition;
}
}, [value, config]);
}, [value]);
return prevValue;
}
function rerenderDeferredValue<T>(
value: T,
config: TimeoutConfig | void | null,
): T {
function rerenderDeferredValue<T>(value: T): T {
const [prevValue, setValue] = rerenderState(value);
updateEffect(() => {
const prevTransition = ReactCurrentBatchConfig.transition;
@ -1479,11 +1465,11 @@ function rerenderDeferredValue<T>(
} finally {
ReactCurrentBatchConfig.transition = prevTransition;
}
}, [value, config]);
}, [value]);
return prevValue;
}
function startTransition(setPending, config, callback) {
function startTransition(setPending, callback) {
const priorityLevel = getCurrentPriorityLevel();
if (decoupleUpdatePriorityFromScheduler) {
const previousLanePriority = getCurrentUpdateLanePriority();
@ -1500,7 +1486,9 @@ function startTransition(setPending, config, callback) {
},
);
// If there's no SuspenseConfig set, we'll use the DefaultLanePriority for this transition.
// TODO: Can remove this. Was only necessary because we used to give
// different behavior to transitions without a config object. Now they are
// all treated the same.
setCurrentUpdateLanePriority(DefaultLanePriority);
runWithPriority(
@ -1545,36 +1533,26 @@ function startTransition(setPending, config, callback) {
}
}
function mountTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
function mountTransition(): [(() => void) => void, boolean] {
const [isPending, setPending] = mountState(false);
const start = mountCallback(startTransition.bind(null, setPending, config), [
setPending,
config,
]);
// The `start` method can be stored on a ref, since `setPending`
// never changes.
const start = startTransition.bind(null, setPending);
mountRef(start);
return [start, isPending];
}
function updateTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
const [isPending, setPending] = updateState(false);
const start = updateCallback(startTransition.bind(null, setPending, config), [
setPending,
config,
]);
function updateTransition(): [(() => void) => void, boolean] {
const [isPending] = updateState(false);
const startRef = updateRef();
const start: (() => void) => void = (startRef.current: any);
return [start, isPending];
}
function rerenderTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
const [isPending, setPending] = rerenderState(false);
const start = updateCallback(startTransition.bind(null, setPending, config), [
setPending,
config,
]);
function rerenderTransition(): [(() => void) => void, boolean] {
const [isPending] = rerenderState(false);
const startRef = updateRef();
const start: (() => void) => void = (startRef.current: any);
return [start, isPending];
}
@ -1986,17 +1964,15 @@ if (__DEV__) {
mountHookTypesDev();
return mountDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
mountHookTypesDev();
return mountDeferredValue(value, config);
return mountDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
mountHookTypesDev();
return mountTransition(config);
return mountTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2110,17 +2086,15 @@ if (__DEV__) {
updateHookTypesDev();
return mountDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
updateHookTypesDev();
return mountDeferredValue(value, config);
return mountDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return mountTransition(config);
return mountTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2234,17 +2208,15 @@ if (__DEV__) {
updateHookTypesDev();
return updateDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
updateHookTypesDev();
return updateDeferredValue(value, config);
return updateDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return updateTransition(config);
return updateTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2359,17 +2331,15 @@ if (__DEV__) {
updateHookTypesDev();
return updateDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
updateHookTypesDev();
return rerenderDeferredValue(value, config);
return rerenderDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return rerenderTransition(config);
return rerenderTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2494,19 +2464,17 @@ if (__DEV__) {
mountHookTypesDev();
return mountDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
warnInvalidHookAccess();
mountHookTypesDev();
return mountDeferredValue(value, config);
return mountDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
mountHookTypesDev();
return mountTransition(config);
return mountTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2633,19 +2601,17 @@ if (__DEV__) {
updateHookTypesDev();
return updateDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
warnInvalidHookAccess();
updateHookTypesDev();
return updateDeferredValue(value, config);
return updateDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
updateHookTypesDev();
return updateTransition(config);
return updateTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2773,19 +2739,17 @@ if (__DEV__) {
updateHookTypesDev();
return updateDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
warnInvalidHookAccess();
updateHookTypesDev();
return rerenderDeferredValue(value, config);
return rerenderDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
updateHookTypesDev();
return rerenderTransition(config);
return rerenderTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,

View File

@ -16,7 +16,6 @@ import type {
import type {Fiber, Dispatcher} from './ReactInternalTypes';
import type {Lanes, Lane} from './ReactFiberLane';
import type {HookEffectTag} from './ReactHookEffectTags';
import type {SuspenseConfig} from './ReactFiberTransition';
import type {ReactPriorityLevel} from './ReactInternalTypes';
import type {FiberRoot} from './ReactInternalTypes';
import type {OpaqueIDType} from './ReactFiberHostConfig';
@ -150,10 +149,6 @@ export type Effect = {|
export type FunctionComponentUpdateQueue = {|lastEffect: Effect | null|};
type TimeoutConfig = {|
timeoutMs: number,
|};
type BasicStateAction<S> = (S => S) | S;
type Dispatch<A> = A => void;
@ -1431,10 +1426,7 @@ function updateMemo<T>(
return nextValue;
}
function mountDeferredValue<T>(
value: T,
config: TimeoutConfig | void | null,
): T {
function mountDeferredValue<T>(value: T): T {
const [prevValue, setValue] = mountState(value);
mountEffect(() => {
const prevTransition = ReactCurrentBatchConfig.transition;
@ -1444,14 +1436,11 @@ function mountDeferredValue<T>(
} finally {
ReactCurrentBatchConfig.transition = prevTransition;
}
}, [value, config]);
}, [value]);
return prevValue;
}
function updateDeferredValue<T>(
value: T,
config: TimeoutConfig | void | null,
): T {
function updateDeferredValue<T>(value: T): T {
const [prevValue, setValue] = updateState(value);
updateEffect(() => {
const prevTransition = ReactCurrentBatchConfig.transition;
@ -1461,14 +1450,11 @@ function updateDeferredValue<T>(
} finally {
ReactCurrentBatchConfig.transition = prevTransition;
}
}, [value, config]);
}, [value]);
return prevValue;
}
function rerenderDeferredValue<T>(
value: T,
config: TimeoutConfig | void | null,
): T {
function rerenderDeferredValue<T>(value: T): T {
const [prevValue, setValue] = rerenderState(value);
updateEffect(() => {
const prevTransition = ReactCurrentBatchConfig.transition;
@ -1478,11 +1464,11 @@ function rerenderDeferredValue<T>(
} finally {
ReactCurrentBatchConfig.transition = prevTransition;
}
}, [value, config]);
}, [value]);
return prevValue;
}
function startTransition(setPending, config, callback) {
function startTransition(setPending, callback) {
const priorityLevel = getCurrentPriorityLevel();
if (decoupleUpdatePriorityFromScheduler) {
const previousLanePriority = getCurrentUpdateLanePriority();
@ -1499,7 +1485,9 @@ function startTransition(setPending, config, callback) {
},
);
// If there's no SuspenseConfig set, we'll use the DefaultLanePriority for this transition.
// TODO: Can remove this. Was only necessary because we used to give
// different behavior to transitions without a config object. Now they are
// all treated the same.
setCurrentUpdateLanePriority(DefaultLanePriority);
runWithPriority(
@ -1544,36 +1532,26 @@ function startTransition(setPending, config, callback) {
}
}
function mountTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
function mountTransition(): [(() => void) => void, boolean] {
const [isPending, setPending] = mountState(false);
const start = mountCallback(startTransition.bind(null, setPending, config), [
setPending,
config,
]);
// The `start` method can be stored on a ref, since `setPending`
// never changes.
const start = startTransition.bind(null, setPending);
mountRef(start);
return [start, isPending];
}
function updateTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
const [isPending, setPending] = updateState(false);
const start = updateCallback(startTransition.bind(null, setPending, config), [
setPending,
config,
]);
function updateTransition(): [(() => void) => void, boolean] {
const [isPending] = updateState(false);
const startRef = updateRef();
const start: (() => void) => void = (startRef.current: any);
return [start, isPending];
}
function rerenderTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
const [isPending, setPending] = rerenderState(false);
const start = updateCallback(startTransition.bind(null, setPending, config), [
setPending,
config,
]);
function rerenderTransition(): [(() => void) => void, boolean] {
const [isPending] = rerenderState(false);
const startRef = updateRef();
const start: (() => void) => void = (startRef.current: any);
return [start, isPending];
}
@ -1984,17 +1962,15 @@ if (__DEV__) {
mountHookTypesDev();
return mountDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
mountHookTypesDev();
return mountDeferredValue(value, config);
return mountDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
mountHookTypesDev();
return mountTransition(config);
return mountTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2108,17 +2084,15 @@ if (__DEV__) {
updateHookTypesDev();
return mountDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
updateHookTypesDev();
return mountDeferredValue(value, config);
return mountDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return mountTransition(config);
return mountTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2232,17 +2206,15 @@ if (__DEV__) {
updateHookTypesDev();
return updateDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
updateHookTypesDev();
return updateDeferredValue(value, config);
return updateDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return updateTransition(config);
return updateTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2357,17 +2329,15 @@ if (__DEV__) {
updateHookTypesDev();
return updateDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
updateHookTypesDev();
return rerenderDeferredValue(value, config);
return rerenderDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
updateHookTypesDev();
return rerenderTransition(config);
return rerenderTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2492,19 +2462,17 @@ if (__DEV__) {
mountHookTypesDev();
return mountDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
warnInvalidHookAccess();
mountHookTypesDev();
return mountDeferredValue(value, config);
return mountDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
mountHookTypesDev();
return mountTransition(config);
return mountTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2631,19 +2599,17 @@ if (__DEV__) {
updateHookTypesDev();
return updateDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
warnInvalidHookAccess();
updateHookTypesDev();
return updateDeferredValue(value, config);
return updateDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
updateHookTypesDev();
return updateTransition(config);
return updateTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
@ -2771,19 +2737,17 @@ if (__DEV__) {
updateHookTypesDev();
return updateDebugValue(value, formatterFn);
},
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {
useDeferredValue<T>(value: T): T {
currentHookNameInDev = 'useDeferredValue';
warnInvalidHookAccess();
updateHookTypesDev();
return rerenderDeferredValue(value, config);
return rerenderDeferredValue(value);
},
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
useTransition(): [(() => void) => void, boolean] {
currentHookNameInDev = 'useTransition';
warnInvalidHookAccess();
updateHookTypesDev();
return rerenderTransition(config);
return rerenderTransition();
},
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,

View File

@ -314,8 +314,8 @@ function throwException(
// that we can show the initial loading state as quickly as possible.
//
// If we hit a "Delayed" case, such as when we'd switch from content back into
// a fallback, then we should always suspend/restart. SuspenseConfig applies to
// this case. If none is defined, JND is used instead.
// a fallback, then we should always suspend/restart. Transitions apply
// to this case. If none is defined, JND is used instead.
//
// If we're already showing a fallback and it gets "retried", allowing us to show
// another level, but there's still an inner boundary that would show a fallback,

View File

@ -316,8 +316,8 @@ function throwException(
// that we can show the initial loading state as quickly as possible.
//
// If we hit a "Delayed" case, such as when we'd switch from content back into
// a fallback, then we should always suspend/restart. SuspenseConfig applies to
// this case. If none is defined, JND is used instead.
// a fallback, then we should always suspend/restart. Transitions apply
// to this case. If none is defined, JND is used instead.
//
// If we're already showing a fallback and it gets "retried", allowing us to show
// another level, but there's still an inner boundary that would show a fallback,

View File

@ -9,18 +9,6 @@
import ReactSharedInternals from 'shared/ReactSharedInternals';
// Deprecated
export type SuspenseConfig = {|
timeoutMs: number,
busyDelayMs?: number,
busyMinDurationMs?: number,
|};
// Deprecated
export type TimeoutConfig = {|
timeoutMs: number,
|};
const {ReactCurrentBatchConfig} = ReactSharedInternals;
export const NoTransition = 0;

View File

@ -27,7 +27,6 @@ import type {RootTag} from './ReactRootTags';
import type {TimeoutHandle, NoTimeout} from './ReactFiberHostConfig';
import type {Wakeable} from 'shared/ReactTypes';
import type {Interaction} from 'scheduler/src/Tracing';
import type {SuspenseConfig, TimeoutConfig} from './ReactFiberTransition';
export type ReactPriorityLevel = 99 | 98 | 97 | 96 | 95 | 90;
@ -291,10 +290,8 @@ export type Dispatcher = {|
deps: Array<mixed> | void | null,
): void,
useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void,
useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T,
useTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean],
useDeferredValue<T>(value: T): T,
useTransition(): [(() => void) => void, boolean],
useMutableSource<Source, Snapshot>(
source: MutableSource<Source>,
getSnapshot: MutableSourceGetSnapshotFn<Source, Snapshot>,

View File

@ -7,15 +7,13 @@
* @flow
*/
import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberTransition';
import ReactCurrentBatchConfig from './ReactCurrentBatchConfig';
// This is a copy of startTransition, except if null or undefined is passed,
// then updates inside the scope are opted-out of the outer transition scope.
// TODO: Deprecated. Remove in favor of startTransition. Figure out how scopes
// should nest, and whether we need an API to opt-out nested scopes.
export function withSuspenseConfig(scope: () => void, config?: SuspenseConfig) {
export function withSuspenseConfig(scope: () => void, config?: mixed) {
const prevTransition = ReactCurrentBatchConfig.transition;
ReactCurrentBatchConfig.transition =
config === undefined || config === null ? 0 : 1;

View File

@ -151,16 +151,14 @@ export function useDebugValue<T>(
export const emptyObject = {};
export function useTransition(
config: ?Object,
): [(() => void) => void, boolean] {
export function useTransition(): [(() => void) => void, boolean] {
const dispatcher = resolveDispatcher();
return dispatcher.useTransition(config);
return dispatcher.useTransition();
}
export function useDeferredValue<T>(value: T, config: ?Object): T {
export function useDeferredValue<T>(value: T): T {
const dispatcher = resolveDispatcher();
return dispatcher.useDeferredValue(value, config);
return dispatcher.useDeferredValue(value);
}
export function useOpaqueIdentifier(): OpaqueIDType | void {