1
votes

In my React app my app component has a function that makes an API call. This function is passed down to child components as a prop and the child components call this function on componentDidMount. When the function in called app.js passes the results of the API call back down to the child components as props.

This all works fine and you can see it at https://codesandbox.io/s/eloquent-roentgen-03dzs (nb when viewing the app in the browser you need to append a username jinky32 to the url https://03dzs.csb.app/ - so https://03dzs.csb.app/jinky32).

However I don't want to keep making unnecessary API calls. Once the components have their wantedCards and ownedCards props I want them to use those, rather than make a fresh API request.

What is the correct way to check that data is loaded into these child component props before calling the loadCardData function? A check if this.props.ownedCards.length < 1 doesn't seem to work for me

2

2 Answers

2
votes

OK, thanks to @RicardoSanchez the move to context was a good one. The fundamental problem however was that in my table component I was using an <a href> to link to other pages and this forced components to remount.

Changing this to <Link to= meant that state was not lost (which was passed down to child components via context api) and I could stop making unneccesary calls!

-2
votes

Maaaan you are doing it wrong, you should use react-redux and redux persist, https://react-redux.js.org/api/hooks, https://www.npmjs.com/package/redux-persist, The first one (redux) keeps your data at a single store, with a single store, there is no need to pass data as props, you always save at the store and retrieve from the store. The persistor keeps the store data saved at your storage (you can choose session or local), and you can use middlewares to check if data already exists before you call the api

here is an example.

export function callApi(payload) {
    try {
      const getProducts = (state) => state.products //access the store
      const products = yield select(getProducts)

      if(products) return;
      yield Axios.get("api/products")
    } catch (err) {
      console.log('error at sagas [getAllProducts type]', err)
    }
}

I'm using sagas as middleware.