Skip to content

Instantly share code, notes, and snippets.

@gpbmike
Created August 8, 2019 17:35
Show Gist options
  • Save gpbmike/53c9469efd50668a6fbc6701bc45f866 to your computer and use it in GitHub Desktop.
Save gpbmike/53c9469efd50668a6fbc6701bc45f866 to your computer and use it in GitHub Desktop.
Share asset requests between components
/*
* Share asset requests between components.
* const { data, loaded, total, error } = useAssetLoader('largeFile.tiff', 'arraybuffer');
*/
import { useEffect, useState } from 'react';
import request from 'superagent';
// Keep track of how many instances are using a each request
// when all instances have been unmounted, we can abort the request
const instances = {};
// Keep track of requests to share between instances
const requests = {};
export default function useAssetLoader(url, responseType) {
const [data, setData] = useState();
const [loaded, setLoaded] = useState();
const [total, setTotal] = useState();
const [error, setError] = useState();
useEffect(() => {
if (!url) {
return () => {};
}
const key = url + responseType;
instances[key] = (instances[key] || 0) + 1;
if (!requests[key]) {
requests[key] = request(url);
if (responseType) {
requests[key].responseType(responseType);
}
}
requests[key].on('progress', (event) => {
if (event.direction === 'download') {
setLoaded(event.loaded);
setTotal(event.total);
}
});
requests[key].on('error', setError);
req.then(response => setData(response.body || response.text));
return () => {
instances[key] -= 1;
// When all components are unmounted we can abort request
if (instances[key] === 0) {
delete instances[key];
if (requests[key]) {
requests[key].abort();
delete requests[key];
}
}
};
}, [url, responseType]);
return { data, loaded, total, error };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment