1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00
next.js/lib/dynamic.js

142 lines
2.9 KiB
JavaScript
Raw Normal View History

import React from 'react'
let currentChunks = []
export default function dynamicComponent (promise, options = {}) {
return class Comp extends React.Component {
constructor (...args) {
super(...args)
2017-04-18 16:51:31 +00:00
this.LoadingComponent = options.loading ? options.loading : () => (<p>loading...</p>)
2017-04-18 16:51:31 +00:00
this.ssr = options.ssr === false ? options.ssr : true
this.state = { AsyncComponent: null }
this.isServer = typeof window === 'undefined'
2017-04-18 16:51:31 +00:00
if (this.ssr) {
this.loadComponent()
}
}
loadComponent () {
promise.then((AsyncComponent) => {
if (this.mounted) {
this.setState({ AsyncComponent })
} else {
if (this.isServer) {
currentChunks.push(AsyncComponent.__webpackChunkName)
}
this.state.AsyncComponent = AsyncComponent
}
})
}
componentDidMount () {
this.mounted = true
2017-04-18 16:51:31 +00:00
if (!this.ssr) {
this.loadComponent()
}
}
render () {
const { AsyncComponent } = this.state
const { LoadingComponent } = this
if (!AsyncComponent) return (<LoadingComponent {...this.props} />)
return <AsyncComponent {...this.props} />
}
}
}
export function flushChunks () {
const chunks = currentChunks
currentChunks = []
return chunks
}
export class SameLoopPromise {
constructor (cb) {
this.onResultCallbacks = []
this.onErrorCallbacks = []
if (cb) {
cb(
(result) => this.setResult(result),
(error) => this.setError(error)
)
}
}
setResult (result) {
this.gotResult = true
this.result = result
this.onResultCallbacks.forEach((cb) => cb(result))
this.onResultCallbacks = []
}
setError (error) {
this.gotError = true
this.error = error
this.onErrorCallbacks.forEach((cb) => cb(error))
this.onErrorCallbacks = []
}
then (onResult, onError) {
const promise = new SameLoopPromise()
const handleError = () => {
if (onError) {
promise.setResult(onError(this.error))
} else {
promise.setError(this.error)
}
}
const handleResult = () => {
promise.setResult(onResult(this.result))
}
if (this.gotResult) {
handleResult()
return promise
}
if (this.gotError) {
handleError()
return promise
}
this.onResultCallbacks.push(handleResult)
this.onErrorCallbacks.push(handleError)
return promise
}
catch (onError) {
const promise = new SameLoopPromise()
const handleError = () => {
promise.setResult(onError(this.error))
}
const handleResult = () => {
promise.setResult(this.result)
}
if (this.gotResult) {
handleResult()
return promise
}
if (this.gotError) {
handleError()
return promise
}
this.onErrorCallbacks.push(handleError)
this.onResultCallbacks.push(handleResult)
return promise
}
}