Skip to content

Instantly share code, notes, and snippets.

@zackify
Created February 19, 2017 17:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zackify/fce7f7eaa317568ad635d9fbad905886 to your computer and use it in GitHub Desktop.
Save zackify/fce7f7eaa317568ad635d9fbad905886 to your computer and use it in GitHub Desktop.
Async link and route components that wait for the bundle (no route change -> empty content -> bundle loads -> page content is now there)
let language = navigator.language.toLowerCase()
if (navigator.languages) language = navigator.languages[0].toLowerCase()
async function loadComponent (path) {
return await System.import(`../../views/${path}`)
}
export async function loadLanguage (path) {
try {
return await System.import(`../../sites/${process.env.SITE_FOLDER}/${path}/${language}`)
} catch (e) {
return await System.import(`../../sites/${process.env.SITE_FOLDER}/${path}/en-us`)
}
}
export async function loadRoute (dataPath) {
if (window.components[dataPath]) return {}
try {
const [ component, text ] = await Promise.all([
loadComponent(dataPath),
loadLanguage(dataPath)
])
if (component) {
window.components[dataPath] = {
component: component.default,
text: text ? text.default : {}
}
}
return { component, text }
} catch (e) {
console.warn(`async route: ${dataPath} does not exist`)
return {}
}
}
import { Route } from 'react-router-dom'
import { loadRoute } from './route-helper'
class Async extends React.Component {
constructor ({ dataPath, ...props }) {
super()
if (window.components[dataPath]) this.state = { ...window.components[dataPath] }
else this.state = {}
}
componentDidMount () {
this.mounted = true
if (!this.state.component) this.load(this.props)
}
componentWillUnmount () {
this.mounted = false
}
componentWillReceiveProps (props) {
if (this.props !== props) this.load(props)
}
async load ({ dataPath }) {
let { component, text } = await loadRoute(dataPath)
if (!component) return
this.setState({
component: component.default,
text: text.default
})
}
render () {
let { component, text } = this.state
if (!component || !text) return null
return React.createElement(component, { ...this.props, text })
}
}
const CustomRoute = props => (
<Route
{...props}
component={Async}
/>
)
export default CustomRoute
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment