Search code examples
javascriptreactjsreact-hooksmemoization

Handle memoizing a component that gets data from API call on an interval in React?


I have a component that needs data from an API call on an interval due to restrictions of the API. I only want to update the state of that component if the API returns a different value, not if the API call returns the same data as last time.

This component is the root of my React app, so my current solution is to create a new root component that does the fetching and will pass down the API response as a prop, and that component receiving the prop will be memoized so it will not update if the response is the same as the previous response prop, but this seems like adding a new component is not needed for this.

I've also tried comparing the current state and the response from the API, but since I'm using hooks, the equality check will always be false because the initial state is always used when re-rendering:

  const [data, setData] = useState({});

  const getData = async () => {
    const testData = await getTestData();
    if (!_.isEqual(data, testData)) { // will always be false
      setData(testData); // will always update
    }
  };

  useEffect(() => {
      const interval = setInterval(() => {
      getData();
    }, 5000);
    return () => clearInterval(interval);
  }, []);

Solution

  • I've also tried comparing the current state and the response from the API, but since I'm using hooks, the equality check will always be false because the initial state is always used when re-rendering:

    If you use the callback version of set state, you can get the latest value. And if you return the previous state, react will skip rerendering the component:

    const getData = async () => {
      const testData = await getTestData();
      setData(prev => {
        if (!_.isEqual(prev, testData)) {
          return testData;
        } else {
          return prev;
        }
      });
    };