Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Triggering a React effect periodically

Consider the following simple React component with an effect that fetches some data and saves it to the component state:

function MyComponent(props) {
  const [data, setData] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const res = await fetch("data.json");
      setData(await res.json());
    };
    fetchData();
  }, []);

  return (
    <></>
  )
}

What is the right way to set this effect to run periodically, say every minute?

Is it as easy as replacing fetchData() with setInterval(fetchData, 60) or are there other React-specific considerations I should be thinking of?

like image 424
Yuval Adam Avatar asked Sep 07 '25 05:09

Yuval Adam


2 Answers

Is it as easy as replacing fetchData() with setInterval(fetchData, 60)

Yes.

Just make sure to do clearInterval (return of useEffect()) when component unmounts.

useEffect(() => {
  const fetchData = async () => {
    const res = await fetch("data.json");
    setData(await res.json());
  };

  const t = setInterval(fetchData, 60000);

  return () => clearInterval(t); // clear
}, []);
like image 51
Joseph D. Avatar answered Sep 09 '25 02:09

Joseph D.


Are there other React-specific considerations I should be thinking of?

Just for the completeness of Joseph's answer, you should consider memoizing the component's children, or it will rerender them on each interval:

//                         v Notice the children
function MyComponent({ children }) {
  const [data, setData] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const res = await fetch('data.json');
      setData(await res.json());
    };

    const interval = setInterval(fetchData, 60000);

    return () => clearInterval(interval);
  }, []);


//            v Causes children to re-render every interval
  return <>{children}</>;
}
export default MyComponent;

Possible case:

<MyComponent>
  <Child />
</MyComponent>

Solution:

// Possible Child
function Child = () => <></>

//                     v Memoization using shallow comparison
export default React.memo(Child);
like image 33
Dennis Vash Avatar answered Sep 09 '25 01:09

Dennis Vash