Skip to content

[feat] New rule react-x/no-circular-(use)-effect to detect circular set functions and deps patterns in useEffect like hooks #755

Open
@Rel1cx

Description

@Rel1cx

Describe the problem

import { useEffect, useState } from "react";

/**
 * @component
 * @description CircularEffect1 has a circular effect with a depth of 1
 */
export function CircularEffect1() {
  const [items, setItems] = useState([0, 1, 2, 3, 4]);

  useEffect(() => {
    setItems(x => [...x].reverse());
  }, [items]);

  return null;
}

/**
 * @component
 * @description CircularEffect2 has a circular effect with a depth of 2
 */
export function CircularEffect2() {
  const [items, setItems] = useState([0, 1, 2, 3, 4]);
  const [limit, setLimit] = useState(false);

  useEffect(() => {
    setItems(x => [...x].reverse());
  }, [limit]);

  // ...Many other hooks between the two `useEffect` calls

  useEffect(() => {
    setLimit(x => !x);
  }, [items]);
  // ...

  return null;
}

/**
 * @component
 * @description CircularEffect3 has a circular effect with a depth of 3
 */
export function CircularEffect3() {
  const [items, setItems] = useState([0, 1, 2, 3, 4]);
  const [limit, setLimit] = useState(false);
  const [count, setCount] = useState(0);

  useEffect(() => {
    setItems(x => [...x].reverse());
  }, [limit]);

  useEffect(() => {
    setCount(x => x + 1);
  }, [items]);

  useEffect(() => {
    setLimit(x => !x);
  }, [count]);

  return null;
}

Describe the solution you'd like

Merge all useEffect like hooks within the same component or custom hook, then detect the calls to set and dispatch functions and the dependencies.

Alternatives considered

Using directed graph to collect and detect circular between useEffect like hooks within the same component or custom hook.

Additional context

#745 (comment)
https://x.com/dan_abramov2/status/1825697422494019851
https://x.com/fraser_drops/status/1825953286786265424
https://x.com/fraser_drops/status/1582408358883397633

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions