Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn when using useFormState #28668

Merged
merged 1 commit into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions packages/react-dom/index.experimental.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,3 @@ export {
preinitModule,
version,
} from './src/client/ReactDOM';

import type {Awaited} from 'shared/ReactTypes';
import type {FormStatus} from 'react-dom-bindings/src/shared/ReactDOMFormActions';
import {useFormStatus, useFormState} from './src/client/ReactDOM';

export function experimental_useFormStatus(): FormStatus {
if (__DEV__) {
console.error(
'useFormStatus is now in canary. Remove the experimental_ prefix. ' +
'The prefixed alias will be removed in an upcoming release.',
);
}
return useFormStatus();
}

export function experimental_useFormState<S, P>(
action: (Awaited<S>, P) => S,
initialState: Awaited<S>,
permalink?: string,
): [Awaited<S>, (P) => void, boolean] {
if (__DEV__) {
console.error(
'useFormState is now in canary. Remove the experimental_ prefix. ' +
'The prefixed alias will be removed in an upcoming release.',
);
}
return useFormState(action, initialState, permalink);
}
10 changes: 10 additions & 0 deletions packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@ describe('ReactDOMFizzServer', () => {
}
PropTypes = require('prop-types');
if (__VARIANT__) {
const originalConsoleError = console.error;
console.error = (error, ...args) => {
if (
typeof error !== 'string' ||
error.indexOf('ReactDOM.useFormState has been deprecated') === -1
) {
originalConsoleError(error, ...args);
}
};

// Remove after API is deleted.
useActionState = ReactDOM.useFormState;
} else {
Expand Down
9 changes: 9 additions & 0 deletions packages/react-dom/src/__tests__/ReactDOMForm-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ describe('ReactDOMForm', () => {
textCache = new Map();

if (__VARIANT__) {
const originalConsoleError = console.error;
console.error = (error, ...args) => {
if (
typeof error !== 'string' ||
error.indexOf('ReactDOM.useFormState has been deprecated') === -1
) {
originalConsoleError(error, ...args);
}
};
// Remove after API is deleted.
useActionState = ReactDOM.useFormState;
} else {
Expand Down
20 changes: 20 additions & 0 deletions packages/react-reconciler/src/ReactFiberHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,12 @@ let didWarnAboutMismatchedHooksForComponent;
let didWarnUncachedGetSnapshot: void | true;
let didWarnAboutUseWrappedInTryCatch;
let didWarnAboutAsyncClientComponent;
let didWarnAboutUseFormState;
if (__DEV__) {
didWarnAboutMismatchedHooksForComponent = new Set<string | null>();
didWarnAboutUseWrappedInTryCatch = new Set<string | null>();
didWarnAboutAsyncClientComponent = new Set<string | null>();
didWarnAboutUseFormState = new Set<string | null>();
}

export type Hook = {
Expand Down Expand Up @@ -386,6 +388,21 @@ function warnOnHookMismatchInDev(currentHookName: HookType): void {
}
}

function warnOnUseFormStateInDev(): void {
if (__DEV__) {
const componentName = getComponentNameFromFiber(currentlyRenderingFiber);
if (!didWarnAboutUseFormState.has(componentName)) {
didWarnAboutUseFormState.add(componentName);

console.error(
'ReactDOM.useFormState has been deprecated and replaced by ' +
'React.useActionState. Please update %s to use React.useActionState.',
componentName,
);
}
}
}

function warnIfAsyncClientComponent(Component: Function) {
if (__DEV__) {
// This dev-only check only works for detecting native async functions,
Expand Down Expand Up @@ -4000,6 +4017,7 @@ if (__DEV__) {
): [Awaited<S>, (P) => void, boolean] {
currentHookNameInDev = 'useFormState';
updateHookTypesDev();
warnOnUseFormStateInDev();
return mountActionState(action, initialState, permalink);
};
(HooksDispatcherOnMountWithHookTypesInDEV: Dispatcher).useActionState =
Expand Down Expand Up @@ -4182,6 +4200,7 @@ if (__DEV__) {
): [Awaited<S>, (P) => void, boolean] {
currentHookNameInDev = 'useFormState';
updateHookTypesDev();
warnOnUseFormStateInDev();
return updateActionState(action, initialState, permalink);
};
(HooksDispatcherOnUpdateInDEV: Dispatcher).useActionState =
Expand Down Expand Up @@ -4364,6 +4383,7 @@ if (__DEV__) {
): [Awaited<S>, (P) => void, boolean] {
currentHookNameInDev = 'useFormState';
updateHookTypesDev();
warnOnUseFormStateInDev();
return rerenderActionState(action, initialState, permalink);
};
(HooksDispatcherOnRerenderInDEV: Dispatcher).useActionState =
Expand Down