Steven R
Steven R

Reputation: 323

Cache like component in reactjs

I'm implementing a cache for the native fetch, and using the latest ReactJS. I was wondering if there was a way to have a global provider or something like that where if a URL exists, just return with the cached data, or if it doesn't, make the call. I dont want to use redux because i dont care about state changes, nor do I want to use local/session storage as well, as i do not want to persist on page refreshed. So I was wondering how I could go about doing this?

I would like to import my Fetch wrapper from anywhere in the application and the fetch wrapper calls the cache to check if the call was made. So for the cache i was hoping for it to be a some global component or provider.

Upvotes: 1

Views: 1682

Answers (2)

charlietfl
charlietfl

Reputation: 171669

Can create a simple class that stores promises internally using urls as keys.

If the stored promise exists you return that and if it doesn't you store a new request promise and return that.

Finally assign a new instance and import that anywhere in your app

class Store {
  constructor() {
    this.store = new Map;
    this.baseUrl = 'https://api.myjson.com/bins/'
  }

  getData(path) {
    let message = 'Cached promise'
    const url = this.baseUrl + path
    let promise = this.store.get(url)
    if (!promise) {
      // if url key doesn't exist in map, create and store new promise
      promise = fetch(url).then(res => res.json());
      message = 'New request promise'
      // store this promise using url as key
      this.store.set(url, promise);
    }
    // remove this `then()` and all `message` references in production code
    // just do `return promise`
    return promise.then(data => [data, 'Path : '+ path, message])
  }

}
// export this to use it anywhere in app
const DataStore = new Store();
// export default DataStore

// run multiple times for various paths 
const bins = ['1cvac6', 'exkuu'];
bins.forEach(path => {
  for (let i = 0; i < 3; i++) {
    DataStore.getData(path).then(res => console.log(JSON.stringify(res)))
  }
})

Note this is only a basic starter and I leave it to you to add error handling

Upvotes: 1

rnmKeshav
rnmKeshav

Reputation: 110

To achieve your requirement you have to store pre-fetched data in your application somehow.

Second way is to use redux which you clearly don't want. Third way could be to use react own state.

Other way could be to keep the fetched data in an javascript object and use that object to check the data. If present return from there. If not fetch data.

Here is suggestion:

var cache = {
    `your_url_1`: {},
    `your_url_2`: {}
}

You can use this object as following:

if (!_.isEmpty(cache[your_url_1])) {
    return cache[your_url_1];
} else {
    var data = fetch(your_url_1);
    cache.your_url_1 = data;

    return data;
}

Note: I am using lodash isEmpty to check if the cache already has some data present. fetch to get the data from your server.

Upvotes: 0

Related Questions