DEV Community

Discussion on: Avoiding Race Conditions when Fetching Data with React Hooks

Collapse
 
smortimerk profile image
Seán Kelleher

One issue that I think is still present in the code is the fact that every tab click is kicking off a new fetch. Instead of only storing the result of a single fetch, you might consider instead saving the results of all (or a subset of all) requests that have completed, and use the currently selected person/tab to index the list of fetched data. I’m more familiar with Vue than React, but the following is a stab at this (untested):

const App = () => {
  const [person, setPerson] = useState(null);
  const [people, setPeople] = useState({});

  useEffect(() => {
    if (!people[person]) {
      setPeople({...people, [person]: {loaded: false, data: ''}});

      fakeFetch(person).then(data => {
        setPeople({...people, [person]: {loaded: true, data}});
      });
    }
  }, [person]);

  return (
    <Fragment>
      <button onClick={() => setPerson('Nick')}>Nick's Profile</button>
      <button onClick={() => setPerson('Deb')}>Deb's Profile</button>
      <button onClick={() => setPerson('Joe')}>Joe's Profile</button>
      {person && (
        <Fragment>
          <h1>{person}</h1>
          <p>{!people[person] || people[person].loading ? 'Loading...' : people[person].data}</p>
        </Fragment>
      )}
    </Fragment>
  );
};
export default App;

This has the added benefit that your navigation state is better decoupled from your object state, meaning that clicking around in your application doesn’t have the potential to leave your data in an inconsistent state if it gets more complicated.

Collapse
 
nas5w profile image
Nick Scialli (he/him) • Edited

It sounds like this concern would be more appropriately managed through cache headers from the backend. In this implementation, it seems the frontend is deciding that the initial data fetch is good for as long as the app is open.

Collapse
 
talha131 profile image
Talha Mansoor

it seems the frontend is deciding that the initial data fetch is good for as long as the app is open.

It is a perfect point.

If we ignore it for a moment please, then my question is, is it possible to leverage useMemo hook for caching data in the example? How will that work?