Last active
August 1, 2019 00:40
-
-
Save jaredpalmer/d0b91593f6baaa2f2867d133a26f4176 to your computer and use it in GitHub Desktop.
SSR HOC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import axios from 'axios'; | |
// This is a Higher Order Component that abstracts duplicated data fetching | |
// on the server and client. | |
export default function SSR(Page) { | |
class SSR extends React.Component { | |
static getInitialData(ctx) { | |
// Need to call the wrapped components getInitialData if it exists | |
return Page.getInitialData | |
? Page.getInitialData(ctx) | |
: Promise.resolve(null); | |
} | |
state = { | |
data: this.props.initialData, | |
isLoading: !!this.props.initialData, | |
}; | |
componentDidMount() { | |
if (!this.state.data) { | |
this.fetchData(); | |
} | |
} | |
fetchData = () => { | |
// if this.state.data is null, that means that the we are on the client. | |
// To get the data we need, we just call getInitialData again on mount. | |
console.log('refetching'); | |
this.setState({ isLoading: true }); | |
this.constructor.getInitialData({ match: this.props.match, axios }).then( | |
data => { | |
this.setState({ data, isLoading: false }); | |
}, | |
error => { | |
this.setState(state => ({ | |
data: { error }, | |
isLoading: false, | |
})); | |
} | |
); | |
}; | |
render() { | |
// Flatten out all the props. | |
const { initialData, ...rest } = this.props; | |
return ( | |
<Page | |
{...rest} | |
refetch={this.fetchData} | |
isLoading={this.state.isLoading} | |
{...this.state.data} | |
/> | |
); | |
} | |
} | |
SSR.displayName = `SSR(${getDisplayName(Page)})`; | |
return SSR; | |
} | |
// This make debugging easier. Components will show as SSR(MyComponent) in | |
// react-dev-tools. | |
function getDisplayName(WrappedComponent) { | |
return WrappedComponent.displayName || WrappedComponent.name || 'Component'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment