Skip to content

Instantly share code, notes, and snippets.

@yyyyaaa
Forked from acdlite/prefetch.js
Created March 25, 2018 05:18
Show Gist options
  • Save yyyyaaa/3a7ee5ed3b134f0eaca75be428e3f110 to your computer and use it in GitHub Desktop.
Save yyyyaaa/3a7ee5ed3b134f0eaca75be428e3f110 to your computer and use it in GitHub Desktop.
Prefetching in React
function prefetch(getKey, getValue, getInitialValue, propName) {
const inFlight = new Set();
const cache = new Map();
return ChildComponent => {
return class extends React.Component {
state = {value: getInitialValue(this.props)};
componentWillReceiveProps(nextProps) {
const key = getKey(nextProps);
if (cache.has(key)) {
// Use cached value
this.setState({value: cache.get(key)});
}
}
async componentWillUpdate(nextProps) {
const key = getKey(nextProps);
if (cache.has(key) || inFlight.has(key)) {
// Request already in-flight
return;
}
inFlight.add(key);
const value = await getValue(key);
inFlight.delete(key);
cache.set(key, value);
this.setState({value});
}
render() {
const props = {[propName]: this.state.value};
return <ChildComponent {...props} />;
}
};
};
}
// Can use on multiple components, will share same internal cache
const prefetchThing = prefetch(
props => props.thingId,
thingId => fetch(`/api/thing/${thingId}`),
() => null,
'thing'
);
function View({thing}) {
if (user === null) {
return <LoadingSpinner />;
}
return <BlahBlahRealCode thing={thing} />;
}
export default prefetchThing(View);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment