Skip to content

Commit 18812b6

Browse files
authored
Warn when using useFormState (#28668)
## Overview useFormState has been replaced with useActionState. Warn when it's used. Also removes the `experimental_useFormState` warnings.
1 parent 19c7c29 commit 18812b6

File tree

4 files changed

+39
-28
lines changed

4 files changed

+39
-28
lines changed

packages/react-dom/index.experimental.js

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,3 @@ export {
2525
preinitModule,
2626
version,
2727
} from './src/client/ReactDOM';
28-
29-
import type {Awaited} from 'shared/ReactTypes';
30-
import type {FormStatus} from 'react-dom-bindings/src/shared/ReactDOMFormActions';
31-
import {useFormStatus, useFormState} from './src/client/ReactDOM';
32-
33-
export function experimental_useFormStatus(): FormStatus {
34-
if (__DEV__) {
35-
console.error(
36-
'useFormStatus is now in canary. Remove the experimental_ prefix. ' +
37-
'The prefixed alias will be removed in an upcoming release.',
38-
);
39-
}
40-
return useFormStatus();
41-
}
42-
43-
export function experimental_useFormState<S, P>(
44-
action: (Awaited<S>, P) => S,
45-
initialState: Awaited<S>,
46-
permalink?: string,
47-
): [Awaited<S>, (P) => void, boolean] {
48-
if (__DEV__) {
49-
console.error(
50-
'useFormState is now in canary. Remove the experimental_ prefix. ' +
51-
'The prefixed alias will be removed in an upcoming release.',
52-
);
53-
}
54-
return useFormState(action, initialState, permalink);
55-
}

packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,16 @@ describe('ReactDOMFizzServer', () => {
100100
}
101101
PropTypes = require('prop-types');
102102
if (__VARIANT__) {
103+
const originalConsoleError = console.error;
104+
console.error = (error, ...args) => {
105+
if (
106+
typeof error !== 'string' ||
107+
error.indexOf('ReactDOM.useFormState has been deprecated') === -1
108+
) {
109+
originalConsoleError(error, ...args);
110+
}
111+
};
112+
103113
// Remove after API is deleted.
104114
useActionState = ReactDOM.useFormState;
105115
} else {

packages/react-dom/src/__tests__/ReactDOMForm-test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ describe('ReactDOMForm', () => {
6262
textCache = new Map();
6363

6464
if (__VARIANT__) {
65+
const originalConsoleError = console.error;
66+
console.error = (error, ...args) => {
67+
if (
68+
typeof error !== 'string' ||
69+
error.indexOf('ReactDOM.useFormState has been deprecated') === -1
70+
) {
71+
originalConsoleError(error, ...args);
72+
}
73+
};
6574
// Remove after API is deleted.
6675
useActionState = ReactDOM.useFormState;
6776
} else {

packages/react-reconciler/src/ReactFiberHooks.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,12 @@ let didWarnAboutMismatchedHooksForComponent;
178178
let didWarnUncachedGetSnapshot: void | true;
179179
let didWarnAboutUseWrappedInTryCatch;
180180
let didWarnAboutAsyncClientComponent;
181+
let didWarnAboutUseFormState;
181182
if (__DEV__) {
182183
didWarnAboutMismatchedHooksForComponent = new Set<string | null>();
183184
didWarnAboutUseWrappedInTryCatch = new Set<string | null>();
184185
didWarnAboutAsyncClientComponent = new Set<string | null>();
186+
didWarnAboutUseFormState = new Set<string | null>();
185187
}
186188

187189
export type Hook = {
@@ -386,6 +388,21 @@ function warnOnHookMismatchInDev(currentHookName: HookType): void {
386388
}
387389
}
388390

391+
function warnOnUseFormStateInDev(): void {
392+
if (__DEV__) {
393+
const componentName = getComponentNameFromFiber(currentlyRenderingFiber);
394+
if (!didWarnAboutUseFormState.has(componentName)) {
395+
didWarnAboutUseFormState.add(componentName);
396+
397+
console.error(
398+
'ReactDOM.useFormState has been deprecated and replaced by ' +
399+
'React.useActionState. Please update %s to use React.useActionState.',
400+
componentName,
401+
);
402+
}
403+
}
404+
}
405+
389406
function warnIfAsyncClientComponent(Component: Function) {
390407
if (__DEV__) {
391408
// This dev-only check only works for detecting native async functions,
@@ -4000,6 +4017,7 @@ if (__DEV__) {
40004017
): [Awaited<S>, (P) => void, boolean] {
40014018
currentHookNameInDev = 'useFormState';
40024019
updateHookTypesDev();
4020+
warnOnUseFormStateInDev();
40034021
return mountActionState(action, initialState, permalink);
40044022
};
40054023
(HooksDispatcherOnMountWithHookTypesInDEV: Dispatcher).useActionState =
@@ -4182,6 +4200,7 @@ if (__DEV__) {
41824200
): [Awaited<S>, (P) => void, boolean] {
41834201
currentHookNameInDev = 'useFormState';
41844202
updateHookTypesDev();
4203+
warnOnUseFormStateInDev();
41854204
return updateActionState(action, initialState, permalink);
41864205
};
41874206
(HooksDispatcherOnUpdateInDEV: Dispatcher).useActionState =
@@ -4364,6 +4383,7 @@ if (__DEV__) {
43644383
): [Awaited<S>, (P) => void, boolean] {
43654384
currentHookNameInDev = 'useFormState';
43664385
updateHookTypesDev();
4386+
warnOnUseFormStateInDev();
43674387
return rerenderActionState(action, initialState, permalink);
43684388
};
43694389
(HooksDispatcherOnRerenderInDEV: Dispatcher).useActionState =

0 commit comments

Comments
 (0)