@samitouri / QOS-React-2 / commits / 1b0132c05a

Consider dispatch from `useActionState` stable (#29665)

Sebastian Silbermann committed Jul 6, 2024 at 08:52 UTC 1b0132c05acabae5aebd32c2cadddfb16bda70bc
2 files changed +57 -2
packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
+50 -1
@@ -607,6 +607,8 @@ const tests = {
607 const [state4, dispatch2] = React.useReducer();
608 const [state5, maybeSetState] = useFunnyState();
609 const [state6, maybeDispatch] = useFunnyReducer();
610 + const [state9, dispatch5] = useActionState();
611 + const [state10, dispatch6] = React.useActionState();
612 const [isPending1] = useTransition();
613 const [isPending2, startTransition2] = useTransition();
614 const [isPending3] = React.useTransition();
@@ -624,6 +626,8 @@ const tests = {
626 setState2();
627 dispatch1();
628 dispatch2();
629 + dispatch5();
630 + dispatch6();
631 startTransition1();
632 startTransition2();
633 startTransition3();
@@ -646,7 +650,7 @@ const tests = {
650 maybeDispatch();
651 }, [
652 // Dynamic
649 - state1, state2, state3, state4, state5, state6,
653 + state1, state2, state3, state4, state5, state6, state9, state10,
654 maybeRef1, maybeRef2,
655 isPending2, isPending4,
656
@@ -1494,6 +1498,51 @@ const tests = {
1498 },
1499 ],
1500 },
1501 + {
1502 + // Affected code should use React.useActionState instead
1503 + code: normalizeIndent`
1504 + function ComponentUsingFormState(props) {
1505 + const [state7, dispatch3] = useFormState();
1506 + const [state8, dispatch4] = ReactDOM.useFormState();
1507 + useEffect(() => {
1508 + dispatch3();
1509 + dispatch4();
1510 +
1511 + // dynamic
1512 + console.log(state7);
1513 + console.log(state8);
1514 +
1515 + }, [state7, state8]);
1516 + }
1517 + `,
1518 + errors: [
1519 + {
1520 + message:
1521 + "React Hook useEffect has missing dependencies: 'dispatch3' and 'dispatch4'. " +
1522 + 'Either include them or remove the dependency array.',
1523 + suggestions: [
1524 + {
1525 + desc: 'Update the dependencies array to be: [dispatch3, dispatch4, state7, state8]',
1526 + output: normalizeIndent`
1527 + function ComponentUsingFormState(props) {
1528 + const [state7, dispatch3] = useFormState();
1529 + const [state8, dispatch4] = ReactDOM.useFormState();
1530 + useEffect(() => {
1531 + dispatch3();
1532 + dispatch4();
1533 +
1534 + // dynamic
1535 + console.log(state7);
1536 + console.log(state8);
1537 +
1538 + }, [dispatch3, dispatch4, state7, state8]);
1539 + }
1540 + `,
1541 + },
1542 + ],
1543 + },
1544 + ],
1545 + },
1546 {
1547 code: normalizeIndent`
1548 function MyComponent(props) {
packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
+7 -1
@@ -179,6 +179,8 @@ export default {
179 // ^^^ true for this reference
180 // const [state, dispatch] = useReducer() / React.useReducer()
181 // ^^^ true for this reference
182 + // const [state, dispatch] = useActionState() / React.useActionState()
183 + // ^^^ true for this reference
184 // const ref = useRef()
185 // ^^^ true for this reference
186 // const onStuff = useEffectEvent(() => {})
@@ -260,7 +262,11 @@ export default {
262 }
263 // useEffectEvent() return value is always unstable.
264 return true;
263 - } else if (name === 'useState' || name === 'useReducer') {
265 + } else if (
266 + name === 'useState' ||
267 + name === 'useReducer' ||
268 + name === 'useActionState'
269 + ) {
270 // Only consider second value in initializing tuple stable.
271 if (
272 id.type === 'ArrayPattern' &&