DOBeR
DOBeR

Reputation: 27

Condition inside setInterval in functional component

I set an interval inside useEffect to update data every 33 seconds if a state variable can_update is true. The initial value for can_pdate = true. The problem is, even if I change can_update to false (using disable_update function), in the update_groups function it still comes as true.

  const [can_update, set_can_update] = useState(true);
  const [groups, set_groups] = useState([]);

  const intervalRef = useRef();

  useEffect(() => {
    update_groups();
    const update_interval = setInterval(() => {
      update_groups();
    }, 33000);
    intervalRef.current = update_interval;
    return () => {
      clearInterval(intervalRef.current);
    };
  }, [project_data.id]);

  const update_groups = () => {
    if (can_update) {
      UI.get(`/project/${project_data.id}/controllers/`).then(
        (data) => {
          set_groups(data.groups);
        },
        (error) => {
          console.log("Не удалось загрузить список групп");
        },
      );
    }
  };

  const enable_update = () => {
    set_can_update(true);
  };

  const disable_update = () => {
    set_can_update(false);
  };

I've tried moving condition into

setInterval: `const update_interval = setInterval(() => {
    if (can_update){ update_groups()};
}

and replacing setInterval for recursive setTimeout. No changes.

I've had somewhat similar code inside a class component, and there didn't seem to be any problems like this.

Upvotes: 2

Views: 1384

Answers (1)

Nikita Madeev
Nikita Madeev

Reputation: 4380

You need add can_update to useEffect deps, otherwise

all values from the component scope (such as props and state) that change over time and that are used by the effect. https://reactjs.org/docs/hooks-effect.html

In your case useEffect was called once, inside it every 33 seconds a function update_groups was called with scoped value can_update = true.

React.useEffect(() => {
    if (can_update) {
        update_groups();
        const update_interval = setInterval(() => {
            update_groups();
        }, 33000);
        intervalRef.current = update_interval;
        return () => {
            clearInterval(intervalRef.current);
        };
    }
}, [project_data.id, can_update]);

const update_groups = () => {
    UI.get(`/project/${project_data.id}/controllers/`).then(
        data => {
            set_groups(data.groups);
        },
        error => {
            console.log('Не удалось загрузить список групп');
        },
    );
};

Upvotes: 1

Related Questions