mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
78
packages/react-reconciler/src/ReactFiberHooks.js
vendored
78
packages/react-reconciler/src/ReactFiberHooks.js
vendored
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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');
|
||||
|
||||
4
packages/react-server/src/ReactFizzHooks.js
vendored
4
packages/react-server/src/ReactFizzHooks.js
vendored
@@ -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);
|
||||
|
||||
@@ -59,7 +59,7 @@ export {
|
||||
useMemo,
|
||||
useMutableSource,
|
||||
useMutableSource as unstable_useMutableSource,
|
||||
experimental_useOptimisticState,
|
||||
experimental_useOptimistic,
|
||||
useReducer,
|
||||
useRef,
|
||||
useState,
|
||||
|
||||
@@ -49,7 +49,7 @@ export {
|
||||
useInsertionEffect,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
experimental_useOptimisticState,
|
||||
experimental_useOptimistic,
|
||||
useReducer,
|
||||
useRef,
|
||||
useState,
|
||||
|
||||
@@ -77,7 +77,7 @@ export {
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useMutableSource,
|
||||
experimental_useOptimisticState,
|
||||
experimental_useOptimistic,
|
||||
useSyncExternalStore,
|
||||
useReducer,
|
||||
useRef,
|
||||
|
||||
@@ -57,7 +57,7 @@ export {
|
||||
useMemo,
|
||||
useMutableSource,
|
||||
useMutableSource as unstable_useMutableSource,
|
||||
experimental_useOptimisticState,
|
||||
experimental_useOptimistic,
|
||||
useReducer,
|
||||
useRef,
|
||||
useState,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user