skip to Main Content

So I have a data response that looks like this –

"data": [
        {
            "_id": "65a52c333972416e3ef579a9",
            "kitchenName": "Micdamilare Cuisine",
            "image": "https://1703115912.png"
        },
        {
            "_id": "65a52c333972416e3ef579d3",
            "kitchenName": "So Fresh",
            "image": "https://1703192022.jpeg"
        },
        {
            "_id": "65a52c333972416e3ef579c8",
            "kitchenName": "The Nest Lounge",
            "image": "https://1703082755.jpeg"
        },
        {
            "_id": "65a52c333972416e3ef579ad",
            "kitchenName": "Bobby Best Continental",
            "image": "https://1705318137.jpeg"
        },
        {
            "_id": "65a5345ae04e780a3a7038db",
            "kitchenName": "Labule",
            "image": "https://1705187022.jpeg"
        },
        // ...more objects here
]

I am using a useeffect to call this endpoint and storing the data in an array. Now this endpoint calls every time I leave the page and come back, rightly so because it is a useeffect but the problem is that the data that comes from the endpoint is not consistent. So what I mean is the order changes, same data but the order changes making the website to always change the location of what is being shown. Someone told me to persist the data and run a condition, I didn’t get what he said well but that after one load the endpoint should not be called again or after one load the data should not be stored in that variable but I am a newbie so I don’t understand what he is trying to say. Can someone please give me easy suggestions on what to do and if possible a code that highlights the process.

I tried storing the data to localstorage and mapping that to display the UI but that is wrong because the data is still being set. Maybe a condition that takes account of a reload will work but I have no idea how to do that.

2

Answers


  1. Chosen as BEST ANSWER

    This is how I solved the problem -

        useEffect(() => {
        const fetchData = async() => {
          try {
            const req = await kitchenStore.getKitchen();
            setKitchen(req);
            sessionStorage.setItem('kitchen', JSON.stringify(req));
          }
          catch (err) {
            console.log('error')
          }
        }
    
        const storedKitchenString = sessionStorage.getItem('kitchen');
        const storedKitchen = storedKitchenString ? JSON.parse(storedKitchenString) : [];
        
        if (storedKitchen && storedKitchen.length > 0) {
          setKitchen(storedKitchen);
        } else {
          fetchData();
        }
      }, [kitchenStore]);
    

    Mobx is what I am using for state management, so what I am doing is save the data when it is called to sessionstorage, so if there is data in the sessionstorage there is no need to call the endpoint again just store what is in sessionstorage to a usestate variable and use that variable on the ui.


  2. I see two approaches you might consider:

    1. sort the data you receive from the API based on some attribute in the data so that the order remains consistent in the UI even if the API returns the data in a different order. So for example the following will sort data in lexigraphical order based on the _id value:
    data.sort((a,b) => a._id < b._id ? 1 : a._id > b._id ? -1 : 0)
    
    1. Move the storage of the data from the API call to a component that is "higher up" in the app’s component tree. You could use a global state management system (e.g. Redux, mobx, Zustrand, etc.) or go with a solution that involves less overhead such as React’s Context API. Then, in your useEffect, you can determine whether the data is already captured: if so, then use the existing data; if not, then call the API and put the returned data into the state solution. Personally, I’d likely go with the Context API approach.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search