Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed lazy usage with Suspense and Error Boundary together #521

Merged
merged 24 commits into from
Sep 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
03eb6d9
Fixed lazy usage with Suspense and Error Boundary together
kamikazePT Feb 4, 2020
d920619
Typo
kamikazePT Feb 4, 2020
c50669e
v1.0.0-fork
kamikazePT Feb 4, 2020
f85fcaa
accidental push
kamikazePT Feb 4, 2020
790ad66
Condition was reversed
kamikazePT Feb 4, 2020
cc0f646
Fixed Suspense with full dynamic import after fulfilled promise
kamikazePT Feb 4, 2020
addb38f
Added unit test
kamikazePT Feb 6, 2020
6ab1221
cached promise
kamikazePT Feb 17, 2020
3e30e69
added tests for multiple elements of same async component
kamikazePT Feb 22, 2020
11d34e8
renamed unit test
kamikazePT Feb 22, 2020
dacc790
added retryable error boundary
kamikazePT Feb 22, 2020
1ca1815
reworked tests
kamikazePT Feb 26, 2020
f9ef9c7
Retrying working for lazy and loadable
kamikazePT Feb 26, 2020
cf9763d
linter should run on pre-commit... :/
kamikazePT Feb 26, 2020
ac57625
upped max bundle size
kamikazePT Feb 28, 2020
df7a4d3
fix: Fixed suspense tests and fixed un-throwable pending promises whe…
kamikazePT Apr 14, 2020
c888a5b
refactor: removed unnecessary wait in test
kamikazePT Apr 14, 2020
97158e2
test: fixed test regarding nested suspense
kamikazePT Apr 14, 2020
4d41215
test: fixed fucked up assertion
kamikazePT Apr 14, 2020
df79086
fix: fixed weird corner case on error boundary not being reached
kamikazePT Apr 15, 2020
8d874f9
chore: merge fix
kamikazePT Aug 4, 2020
d0d4c39
feat: removed proxy
kamikazePT Aug 7, 2020
a15d07a
fix: removed unnecessary code
kamikazePT Sep 4, 2020
72b28dd
fix: fixed unnecesssary stack of callbacks
kamikazePT Sep 4, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ module.exports = {
['@babel/preset-env', { loose: true, targets: getTargets() }],
],
plugins: ['@babel/plugin-proposal-class-properties'],
env: {
test: {
plugins: ['@babel/plugin-proposal-function-bind'],
},
},
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@babel/core": "^7.7.7",
"@babel/node": "^7.7.7",
"@babel/plugin-proposal-class-properties": "^7.7.4",
"@babel/plugin-proposal-function-bind": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.7.6",
"@babel/preset-env": "^7.7.7",
"@babel/preset-react": "^7.7.4",
Expand Down
87 changes: 51 additions & 36 deletions packages/component/src/createLoadable.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { invariant } from './util'
import Context from './Context'
import { LOADABLE_SHARED } from './shared'

const STATUS_PENDING = 'PENDING'
const STATUS_RESOLVED = 'RESOLVED'
const STATUS_REJECTED = 'REJECTED'

function resolveConstructor(ctor) {
if (typeof ctor === 'function') {
return { requireAsync: ctor }
Expand Down Expand Up @@ -75,8 +79,6 @@ function createLoadable({
cacheKey: getCacheKey(props),
}

this.promise = null

invariant(
!props.__chunkExtractor || ctor.requireSync,
'SSR requires `@loadable/babel-plugin`, please install it',
Expand Down Expand Up @@ -119,18 +121,22 @@ function createLoadable({
componentDidMount() {
this.mounted = true

if (this.state.loading) {
this.loadAsync()
} else if (!this.state.error) {
this.triggerOnLoad()
const cachedPromise = this.getCache()

if (cachedPromise && cachedPromise.status === STATUS_REJECTED) {
this.setCache()
this.setState({
error: undefined,
loading: true,
})
}
this.loadAsyncOnLifecycle()
}

componentDidUpdate(prevProps, prevState) {
// Component is reloaded if the cacheKey has changed
if (prevState.cacheKey !== this.state.cacheKey) {
this.promise = null
this.loadAsync()
this.loadAsyncOnLifecycle()
}
}

Expand Down Expand Up @@ -178,29 +184,45 @@ function createLoadable({
}

loadAsync() {
if (!this.promise) {
const { __chunkExtractor, forwardedRef, ...props } = this.props
this.promise = ctor
.requireAsync(props)
const { __chunkExtractor, forwardedRef, ...props } = this.props

let promise = this.getCache()

if (!promise) {
promise = ctor.requireAsync(props)
promise.status = STATUS_PENDING

this.setCache(promise)

const cachedPromise = promise

promise = promise
.then(loadedModule => {
const result = resolve(loadedModule, this.props, Loadable)
if (options.suspense) {
this.setCache(result)
}
this.safeSetState(
{
result: resolve(loadedModule, this.props, Loadable),
loading: false,
},
() => this.triggerOnLoad(),
)
cachedPromise.status = STATUS_RESOLVED
return loadedModule
})
.catch(error => {
this.safeSetState({ error, loading: false })
cachedPromise.status = STATUS_REJECTED
throw error
})
}

return this.promise
return promise
}

loadAsyncOnLifecycle() {
this.loadAsync()
.then(loadedModule => {
const result = resolve(loadedModule, this.props, { Loadable })
this.safeSetState(
{
result,
loading: false,
},
() => this.triggerOnLoad(),
)
})
.catch(error => this.safeSetState({ error, loading: false }))
}

render() {
Expand All @@ -213,15 +235,10 @@ function createLoadable({
const { error, loading, result } = this.state

if (options.suspense) {
const cachedResult = this.getCache()
if (!cachedResult) throw this.loadAsync()
return render({
loading: false,
fallback: null,
result: cachedResult,
options,
props: { ...props, ref: forwardedRef },
})
const cachedPromise = this.getCache()
if (!cachedPromise || cachedPromise.status === STATUS_PENDING) {
throw this.loadAsync()
}
}

if (error) {
Expand All @@ -235,8 +252,6 @@ function createLoadable({
}

return render({
loading,
fallback,
result,
options,
props: { ...props, ref: forwardedRef },
Expand Down
4 changes: 2 additions & 2 deletions packages/component/src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export const { loadable, lazy } = createLoadable({
}
}
},
render({ result, loading, props }) {
if (!loading && props.children) {
render({ result, props }) {
if (props.children) {
return props.children(result)
}

Expand Down
Loading