useOptimisticState -> useOptimistic (#26772)

Drop the "state". Just "useOptimistic". It's cleaner.

This is still an experimental API. May not be the final name.
This commit is contained in:
Andrew Clark
2023-05-03 14:26:00 -04:00
committed by GitHub
parent 388686f291
commit b7972822b5
11 changed files with 65 additions and 69 deletions

View File

@@ -22,7 +22,7 @@ let React;
let ReactDOMServer;
let ReactDOMClient;
let useFormStatus;
let useOptimisticState;
let useOptimistic;
describe('ReactDOMFizzForm', () => {
beforeEach(() => {
@@ -31,7 +31,7 @@ describe('ReactDOMFizzForm', () => {
ReactDOMServer = require('react-dom/server.browser');
ReactDOMClient = require('react-dom/client');
useFormStatus = require('react-dom').experimental_useFormStatus;
useOptimisticState = require('react').experimental_useOptimisticState;
useOptimistic = require('react').experimental_useOptimistic;
act = require('internal-test-utils').act;
container = document.createElement('div');
document.body.appendChild(container);
@@ -454,9 +454,9 @@ describe('ReactDOMFizzForm', () => {
});
// @gate enableAsyncActions
it('useOptimisticState returns passthrough value', async () => {
it('useOptimistic returns passthrough value', async () => {
function App() {
const [optimisticState] = useOptimisticState('hi');
const [optimisticState] = useOptimistic('hi');
return optimisticState;
}

View File

@@ -1987,7 +1987,7 @@ function rerenderState<S>(
return rerenderReducer(basicStateReducer, initialState);
}
function mountOptimisticState<S, A>(
function mountOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
@@ -2013,7 +2013,7 @@ function mountOptimisticState<S, A>(
return [passthrough, dispatch];
}
function updateOptimisticState<S, A>(
function updateOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
@@ -2034,11 +2034,11 @@ function updateOptimisticState<S, A>(
return updateReducerImpl(hook, ((currentHook: any): Hook), resolvedReducer);
}
function rerenderOptimisticState<S, A>(
function rerenderOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
// Unlike useState, useOptimisticState doesn't support render phase updates.
// Unlike useState, useOptimistic doesn't support render phase updates.
// Also unlike useState, we need to replay all pending updates again in case
// the passthrough value changed.
//
@@ -2048,7 +2048,7 @@ function rerenderOptimisticState<S, A>(
if (currentHook !== null) {
// This is an update. Process the update queue.
return updateOptimisticState(passthrough, reducer);
return updateOptimistic(passthrough, reducer);
}
// This is a mount. No updates to process.
@@ -3207,8 +3207,7 @@ if (enableFormActions && enableAsyncActions) {
throwInvalidHookError;
}
if (enableAsyncActions) {
(ContextOnlyDispatcher: Dispatcher).useOptimisticState =
throwInvalidHookError;
(ContextOnlyDispatcher: Dispatcher).useOptimistic = throwInvalidHookError;
}
const HooksDispatcherOnMount: Dispatcher = {
@@ -3246,8 +3245,7 @@ if (enableFormActions && enableAsyncActions) {
useHostTransitionStatus;
}
if (enableAsyncActions) {
(HooksDispatcherOnMount: Dispatcher).useOptimisticState =
mountOptimisticState;
(HooksDispatcherOnMount: Dispatcher).useOptimistic = mountOptimistic;
}
const HooksDispatcherOnUpdate: Dispatcher = {
@@ -3285,8 +3283,7 @@ if (enableFormActions && enableAsyncActions) {
useHostTransitionStatus;
}
if (enableAsyncActions) {
(HooksDispatcherOnUpdate: Dispatcher).useOptimisticState =
updateOptimisticState;
(HooksDispatcherOnUpdate: Dispatcher).useOptimistic = updateOptimistic;
}
const HooksDispatcherOnRerender: Dispatcher = {
@@ -3324,8 +3321,7 @@ if (enableFormActions && enableAsyncActions) {
useHostTransitionStatus;
}
if (enableAsyncActions) {
(HooksDispatcherOnRerender: Dispatcher).useOptimisticState =
rerenderOptimisticState;
(HooksDispatcherOnRerender: Dispatcher).useOptimistic = rerenderOptimistic;
}
let HooksDispatcherOnMountInDEV: Dispatcher | null = null;
@@ -3518,14 +3514,14 @@ if (__DEV__) {
useHostTransitionStatus;
}
if (enableAsyncActions) {
(HooksDispatcherOnMountInDEV: Dispatcher).useOptimisticState =
function useOptimisticState<S, A>(
(HooksDispatcherOnMountInDEV: Dispatcher).useOptimistic =
function useOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
currentHookNameInDev = 'useOptimisticState';
currentHookNameInDev = 'useOptimistic';
mountHookTypesDev();
return mountOptimisticState(passthrough, reducer);
return mountOptimistic(passthrough, reducer);
};
}
@@ -3687,14 +3683,14 @@ if (__DEV__) {
useHostTransitionStatus;
}
if (enableAsyncActions) {
(HooksDispatcherOnMountWithHookTypesInDEV: Dispatcher).useOptimisticState =
function useOptimisticState<S, A>(
(HooksDispatcherOnMountWithHookTypesInDEV: Dispatcher).useOptimistic =
function useOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
currentHookNameInDev = 'useOptimisticState';
currentHookNameInDev = 'useOptimistic';
updateHookTypesDev();
return mountOptimisticState(passthrough, reducer);
return mountOptimistic(passthrough, reducer);
};
}
@@ -3858,14 +3854,14 @@ if (__DEV__) {
useHostTransitionStatus;
}
if (enableAsyncActions) {
(HooksDispatcherOnUpdateInDEV: Dispatcher).useOptimisticState =
function useOptimisticState<S, A>(
(HooksDispatcherOnUpdateInDEV: Dispatcher).useOptimistic =
function useOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
currentHookNameInDev = 'useOptimisticState';
currentHookNameInDev = 'useOptimistic';
updateHookTypesDev();
return updateOptimisticState(passthrough, reducer);
return updateOptimistic(passthrough, reducer);
};
}
@@ -4029,14 +4025,14 @@ if (__DEV__) {
useHostTransitionStatus;
}
if (enableAsyncActions) {
(HooksDispatcherOnRerenderInDEV: Dispatcher).useOptimisticState =
function useOptimisticState<S, A>(
(HooksDispatcherOnRerenderInDEV: Dispatcher).useOptimistic =
function useOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
currentHookNameInDev = 'useOptimisticState';
currentHookNameInDev = 'useOptimistic';
updateHookTypesDev();
return rerenderOptimisticState(passthrough, reducer);
return rerenderOptimistic(passthrough, reducer);
};
}
@@ -4222,15 +4218,15 @@ if (__DEV__) {
useHostTransitionStatus;
}
if (enableAsyncActions) {
(InvalidNestedHooksDispatcherOnMountInDEV: Dispatcher).useOptimisticState =
function useOptimisticState<S, A>(
(InvalidNestedHooksDispatcherOnMountInDEV: Dispatcher).useOptimistic =
function useOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
currentHookNameInDev = 'useOptimisticState';
currentHookNameInDev = 'useOptimistic';
warnInvalidHookAccess();
mountHookTypesDev();
return mountOptimisticState(passthrough, reducer);
return mountOptimistic(passthrough, reducer);
};
}
@@ -4419,15 +4415,15 @@ if (__DEV__) {
useHostTransitionStatus;
}
if (enableAsyncActions) {
(InvalidNestedHooksDispatcherOnUpdateInDEV: Dispatcher).useOptimisticState =
function useOptimisticState<S, A>(
(InvalidNestedHooksDispatcherOnUpdateInDEV: Dispatcher).useOptimistic =
function useOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
currentHookNameInDev = 'useOptimisticState';
currentHookNameInDev = 'useOptimistic';
warnInvalidHookAccess();
updateHookTypesDev();
return updateOptimisticState(passthrough, reducer);
return updateOptimistic(passthrough, reducer);
};
}
@@ -4616,15 +4612,15 @@ if (__DEV__) {
useHostTransitionStatus;
}
if (enableAsyncActions) {
(InvalidNestedHooksDispatcherOnRerenderInDEV: Dispatcher).useOptimisticState =
function useOptimisticState<S, A>(
(InvalidNestedHooksDispatcherOnRerenderInDEV: Dispatcher).useOptimistic =
function useOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
currentHookNameInDev = 'useOptimisticState';
currentHookNameInDev = 'useOptimistic';
warnInvalidHookAccess();
updateHookTypesDev();
return rerenderOptimisticState(passthrough, reducer);
return rerenderOptimistic(passthrough, reducer);
};
}
}

View File

@@ -58,7 +58,7 @@ export type HookType =
| 'useSyncExternalStore'
| 'useId'
| 'useCacheRefresh'
| 'useOptimisticState';
| 'useOptimistic';
export type ContextDependency<T> = {
context: ReactContext<T>,
@@ -424,7 +424,7 @@ export type Dispatcher = {
useCacheRefresh?: () => <T>(?() => T, ?T) => void,
useMemoCache?: (size: number) => Array<any>,
useHostTransitionStatus?: () => TransitionStatus,
useOptimisticState?: <S, A>(
useOptimistic?: <S, A>(
passthrough: S,
reducer: ?(S, A) => S,
) => [S, (A) => void],

View File

@@ -5,7 +5,7 @@ let act;
let assertLog;
let useTransition;
let useState;
let useOptimisticState;
let useOptimistic;
let textCache;
describe('ReactAsyncActions', () => {
@@ -19,7 +19,7 @@ describe('ReactAsyncActions', () => {
assertLog = require('internal-test-utils').assertLog;
useTransition = React.useTransition;
useState = React.useState;
useOptimisticState = React.experimental_useOptimisticState;
useOptimistic = React.experimental_useOptimistic;
textCache = new Map();
});
@@ -648,12 +648,12 @@ describe('ReactAsyncActions', () => {
});
// @gate enableAsyncActions
test('useOptimisticState can be used to implement a pending state', async () => {
test('useOptimistic can be used to implement a pending state', async () => {
const startTransition = React.startTransition;
let setIsPending;
function App({text}) {
const [isPending, _setIsPending] = useOptimisticState(false);
const [isPending, _setIsPending] = useOptimistic(false);
setIsPending = _setIsPending;
return (
<>
@@ -698,7 +698,7 @@ describe('ReactAsyncActions', () => {
});
// @gate enableAsyncActions
test('useOptimisticState rebases pending updates on top of passthrough value', async () => {
test('useOptimistic rebases pending updates on top of passthrough value', async () => {
let serverCart = ['A'];
async function submitNewItem(item) {
@@ -715,7 +715,7 @@ describe('ReactAsyncActions', () => {
const savedCartSize = cart.length;
const [optimisticCartSize, setOptimisticCartSize] =
useOptimisticState(savedCartSize);
useOptimistic(savedCartSize);
addItemToCart = item => {
startTransition(async () => {
@@ -819,7 +819,7 @@ describe('ReactAsyncActions', () => {
});
// @gate enableAsyncActions
test('useOptimisticState accepts a custom reducer', async () => {
test('useOptimistic accepts a custom reducer', async () => {
let serverCart = ['A'];
async function submitNewItem(item) {
@@ -835,7 +835,7 @@ describe('ReactAsyncActions', () => {
const [isPending, startTransition] = useTransition();
const savedCartSize = cart.length;
const [optimisticCartSize, addToOptimisticCart] = useOptimisticState(
const [optimisticCartSize, addToOptimisticCart] = useOptimistic(
savedCartSize,
(prevSize, newItem) => {
Scheduler.log('Increment optimistic cart size for ' + newItem);
@@ -951,7 +951,7 @@ describe('ReactAsyncActions', () => {
});
// @gate enableAsyncActions
test('useOptimisticState rebases if the passthrough is updated during a render phase update', async () => {
test('useOptimistic rebases if the passthrough is updated during a render phase update', async () => {
// This is kind of an esoteric case where it's hard to come up with a
// realistic real-world scenario but it should still work.
let increment;
@@ -961,7 +961,7 @@ describe('ReactAsyncActions', () => {
const [count, _setCount] = useState(0);
setCount = _setCount;
const [optimisticCount, setOptimisticCount] = useOptimisticState(
const [optimisticCount, setOptimisticCount] = useOptimistic(
count,
prev => {
Scheduler.log('Increment optimistic count');
@@ -1036,12 +1036,12 @@ describe('ReactAsyncActions', () => {
});
// @gate enableAsyncActions
test('useOptimisticState rebases if the passthrough is updated during a render phase update (initial mount)', async () => {
test('useOptimistic rebases if the passthrough is updated during a render phase update (initial mount)', async () => {
// This is kind of an esoteric case where it's hard to come up with a
// realistic real-world scenario but it should still work.
function App() {
const [count, setCount] = useState(0);
const [optimisticCount] = useOptimisticState(count);
const [optimisticCount] = useOptimistic(count);
if (count === 0) {
Scheduler.log('Render phase update count from 1 to 2');

View File

@@ -557,7 +557,7 @@ function unsupportedSetOptimisticState() {
throw new Error('Cannot update optimistic state while rendering.');
}
function useOptimisticState<S, A>(
function useOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
@@ -665,7 +665,7 @@ if (enableFormActions && enableAsyncActions) {
HooksDispatcher.useHostTransitionStatus = useHostTransitionStatus;
}
if (enableAsyncActions) {
HooksDispatcher.useOptimisticState = useOptimisticState;
HooksDispatcher.useOptimistic = useOptimistic;
}
export let currentResponseState: null | ResponseState = (null: any);

View File

@@ -59,7 +59,7 @@ export {
useMemo,
useMutableSource,
useMutableSource as unstable_useMutableSource,
experimental_useOptimisticState,
experimental_useOptimistic,
useReducer,
useRef,
useState,

View File

@@ -49,7 +49,7 @@ export {
useInsertionEffect,
useLayoutEffect,
useMemo,
experimental_useOptimisticState,
experimental_useOptimistic,
useReducer,
useRef,
useState,

View File

@@ -77,7 +77,7 @@ export {
useLayoutEffect,
useMemo,
useMutableSource,
experimental_useOptimisticState,
experimental_useOptimistic,
useSyncExternalStore,
useReducer,
useRef,

View File

@@ -57,7 +57,7 @@ export {
useMemo,
useMutableSource,
useMutableSource as unstable_useMutableSource,
experimental_useOptimisticState,
experimental_useOptimistic,
useReducer,
useRef,
useState,

View File

@@ -59,7 +59,7 @@ import {
useCacheRefresh,
use,
useMemoCache,
useOptimisticState,
useOptimistic,
} from './ReactHooks';
import {
createElementWithValidation,
@@ -113,7 +113,7 @@ export {
useLayoutEffect,
useMemo,
useMutableSource,
useOptimisticState as experimental_useOptimisticState,
useOptimistic as experimental_useOptimistic,
useSyncExternalStore,
useReducer,
useRef,

View File

@@ -242,11 +242,11 @@ export function useEffectEvent<Args, F: (...Array<Args>) => mixed>(
return dispatcher.useEffectEvent(callback);
}
export function useOptimisticState<S, A>(
export function useOptimistic<S, A>(
passthrough: S,
reducer: ?(S, A) => S,
): [S, (A) => void] {
const dispatcher = resolveDispatcher();
// $FlowFixMe[not-a-function] This is unstable, thus optional
return dispatcher.useOptimisticState(passthrough, reducer);
return dispatcher.useOptimistic(passthrough, reducer);
}