Repository: facebook/react
Pull request: Consider dispatch from `useActionState` stable

## Summary

The dispatch function from `useState` and `useReducer` is stable so `exhaustive-deps` doesn't require them to be in dependencies. This applies the same rule to `useActionState` and `useFormState`

## How did you test this change?

- `yarn test packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js` fails with on the first commit but passes on the second.


Changed files:
filename: packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
patch: @@ -607,6 +607,8 @@ const tests = {
           const [state4, dispatch2] = React.useReducer();
           const [state5, maybeSetState] = useFunnyState();
           const [state6, maybeDispatch] = useFunnyReducer();
+          const [state9, dispatch5] = useActionState();
+          const [state10, dispatch6] = React.useActionState();
           const [isPending1] = useTransition();
           const [isPending2, startTransition2] = useTransition();
           const [isPending3] = React.useTransition();
@@ -624,6 +626,8 @@ const tests = {
             setState2();
             dispatch1();
             dispatch2();
+            dispatch5();
+            dispatch6();
             startTransition1();
             startTransition2();
             startTransition3();
@@ -646,7 +650,7 @@ const tests = {
             maybeDispatch();
           }, [
             // Dynamic
-            state1, state2, state3, state4, state5, state6,
+            state1, state2, state3, state4, state5, state6, state9, state10,
             maybeRef1, maybeRef2,
             isPending2, isPending4,
 
@@ -1494,6 +1498,51 @@ const tests = {
         },
       ],
     },
+    {
+      // Affected code should use React.useActionState instead
+      code: normalizeIndent`
+        function ComponentUsingFormState(props) {
+          const [state7, dispatch3] = useFormState();
+          const [state8, dispatch4] = ReactDOM.useFormState();
+          useEffect(() => {
+            dispatch3();
+            dispatch4();
+
+            // dynamic
+            console.log(state7);
+            console.log(state8);
+
+          }, [state7, state8]);
+        }
+      `,
+      errors: [
+        {
+          message:
+            "React Hook useEffect has missing dependencies: 'dispatch3' and 'dispatch4'. " +
+            'Either include them or remove the dependency array.',
+          suggestions: [
+            {
+              desc: 'Update the dependencies array to be: [dispatch3, dispatch4, state7, state8]',
+              output: normalizeIndent`
+                function ComponentUsingFormState(props) {
+                  const [state7, dispatch3] = useFormState();
+                  const [state8, dispatch4] = ReactDOM.useFormState();
+                  useEffect(() => {
+                    dispatch3();
+                    dispatch4();
+
+                    // dynamic
+                    console.log(state7);
+                    console.log(state8);
+
+                  }, [dispatch3, dispatch4, state7, state8]);
+                }
+              `,
+            },
+          ],
+        },
+      ],
+    },
     {
       code: normalizeIndent`
         function MyComponent(props) {

filename: packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
patch: @@ -179,6 +179,8 @@ export default {
       //               ^^^ true for this reference
       // const [state, dispatch] = useReducer() / React.useReducer()
       //               ^^^ true for this reference
+      // const [state, dispatch] = useActionState() / React.useActionState()
+      //               ^^^ true for this reference
       // const ref = useRef()
       //       ^^^ true for this reference
       // const onStuff = useEffectEvent(() => {})
@@ -260,7 +262,11 @@ export default {
           }
           // useEffectEvent() return value is always unstable.
           return true;
-        } else if (name === 'useState' || name === 'useReducer') {
+        } else if (
+          name === 'useState' ||
+          name === 'useReducer' ||
+          name === 'useActionState'
+        ) {
           // Only consider second value in initializing tuple stable.
           if (
             id.type === 'ArrayPattern' &&