Reputation: 323
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
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
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