Skip to content

Instantly share code, notes, and snippets.

@barbagrigia
Forked from acdlite/prefetch.js
Created September 21, 2017 02:11
Show Gist options
  • Save barbagrigia/0b6ee73e2fd49c46b4bb312ad1fbd3ec to your computer and use it in GitHub Desktop.
Save barbagrigia/0b6ee73e2fd49c46b4bb312ad1fbd3ec 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