Home > Software design >  How to avoid re-rendering while loading data from a REST api
How to avoid re-rendering while loading data from a REST api

Time:10-20

I'm trying to load initial data inside a component based on an external variable. So I have this:

const { dossierId } = useParams();
const { loadDossierData } = useDossierContext();

useEffect(() => {
  loadDossierData(dossierId);
}, [dossierId]);

So my application is receiving in the url a parameter called dossierId. This parameter is used to load some initial data that must be stored in an accessible for all context.

The context looks like this:

  const [dossier, setDossier] = useState({});
  const { get } = useRestServices();

  const loadDossierData = async (dossierId) => {
    const result = await get('myurl/%/dossier', [dossierId]); // This 'get' wrapper just substitutes every % in the url by the items in the following array in the function
    setDossier(result);
    console.log('loadDossierData');
    console.log(result);
  };

  return (
    <DossierContext.Provider
      value={{
        dossier,
        loadDossierData,
      }}
    >
      {children}
    </DossierContext.Provider>
  );
};

export const useDossierContext = () => useCustomContext(DossierContext);

export default DossierProvider;

So this looks like a normal code:

  1. The application loads with an initial dossierId
  2. A call to loadDossierData is done with that new dossierId
  3. A REST call is made and data is loaded from backend
  4. The context state updates and the updated dossier variable is visible for everyone who wants to use it

This is the ideal flow, and I can see it working correct because of the forced console.log:

enter image description here

Nice, no?

But the real problem comes here. In the initial call to the function, where I try to detect any dossierId change, the useEffect is warning me about a missing dependency:

enter image description here

But if I add it to the dependency array, my application runs in an infinite loop:

enter image description here

I'm trying to improve the way this information is get and stored in a shared context, but I keep fighting with this re-render thing and I didn't find a solution yet.

Any idea on how to avoid this? I know why the re-render is happening, but I need this flow and I'm not sure on how to do it and avoid re-renders.

Thanks a lot!

CodePudding user response:

You have to use useCallback to prevent loadDossierData from re-rendering.

  const loadDossierData = useCallback(async (dossierId) => {
    const result = await get('myurl/%/dossier', [dossierId]); // This 'get' wrapper just substitutes every % in the url by the items in the following array in the function
    setDossier(result);
    console.log('loadDossierData');
    console.log(result);
  }, [setDossier]);
  • Related