Repository: facebook/react
Pull request: Warn for useFormState on initial render

This was missed in the mount dev dispatcher. It was only in the rerender dispatcher which means that it was only logged during the rerender. Since DevTools can hide logs during rerenders, this hid the warning in StrictMode.

Changed files:
filename: fixtures/flight/src/Counter.js
patch: @@ -1,12 +1,11 @@
 'use client';
 
 import * as React from 'react';
-import {useFormState} from 'react-dom';
 
 import Container from './Container.js';
 
 export function Counter({incrementAction}) {
-  const [count, incrementFormAction] = useFormState(incrementAction, 0);
+  const [count, incrementFormAction] = React.useActionState(incrementAction, 0);
   return (
     <Container>
       <form>

filename: packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js
patch: @@ -11,7 +11,6 @@
 'use strict';
 
 let React;
-let ReactDOM;
 let ReactTestRenderer;
 let ReactDebugTools;
 let act;
@@ -34,7 +33,6 @@ describe('ReactHooksInspectionIntegration', () => {
     jest.resetModules();
     React = require('react');
     ReactTestRenderer = require('react-test-renderer');
-    ReactDOM = require('react-dom');
     act = require('internal-test-utils').act;
     ReactDebugTools = require('react-debug-tools');
     useMemoCache = require('react/compiler-runtime').c;
@@ -2658,9 +2656,9 @@ describe('ReactHooksInspectionIntegration', () => {
   });
 
   // @gate enableAsyncActions
-  it('should support useFormState hook', async () => {
+  it('should support useActionState hook', async () => {
     function Foo() {
-      const [value] = ReactDOM.useFormState(function increment(n) {
+      const [value] = React.useActionState(function increment(n) {
         return n;
       }, 0);
       React.useMemo(() => 'memo', []);
@@ -2689,7 +2687,7 @@ describe('ReactHooksInspectionIntegration', () => {
           },
           "id": 0,
           "isStateEditable": false,
-          "name": "FormState",
+          "name": "ActionState",
           "subHooks": [],
           "value": 0,
         },

filename: packages/react-dom/src/__tests__/ReactDOMFizzForm-test.js
patch: @@ -40,12 +40,12 @@ describe('ReactDOMFizzForm', () => {
     act = require('internal-test-utils').act;
     container = document.createElement('div');
     document.body.appendChild(container);
-    if (__VARIANT__) {
-      // Remove after API is deleted.
-      useActionState = require('react-dom').useFormState;
-    } else {
-      useActionState = require('react').useActionState;
-    }
+    // TODO: Test the old api but it warns so needs warnings to be asserted.
+    // if (__VARIANT__) {
+    // Remove after API is deleted.
+    // useActionState = require('react-dom').useFormState;
+    // }
+    useActionState = require('react').useActionState;
   });
 
   afterEach(() => {

filename: packages/react-reconciler/src/ReactFiberHooks.js
patch: @@ -3994,6 +3994,7 @@ if (__DEV__) {
       ): [Awaited<S>, (P) => void, boolean] {
         currentHookNameInDev = 'useFormState';
         mountHookTypesDev();
+        warnOnUseFormStateInDev();
         return mountActionState(action, initialState, permalink);
       };
     (HooksDispatcherOnMountInDEV: Dispatcher).useActionState =

filename: packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMForm-test.js
patch: @@ -73,12 +73,12 @@ describe('ReactFlightDOMForm', () => {
     ReactDOMClient = require('react-dom/client');
     act = React.act;
 
-    if (__VARIANT__) {
-      // Remove after API is deleted.
-      useActionState = require('react-dom').useFormState;
-    } else {
-      useActionState = require('react').useActionState;
-    }
+    // TODO: Test the old api but it warns so needs warnings to be asserted.
+    // if (__VARIANT__) {
+    // Remove after API is deleted.
+    // useActionState = require('react-dom').useFormState;
+    // }
+    useActionState = require('react').useActionState;
     container = document.createElement('div');
     document.body.appendChild(container);
   });