Prevent extraneous re-renders with next/dynamic (#11587)

* Prevent extraneous rerenders with loadables

* Don't try to spread undefined

* Allow ref to be memoized
This commit is contained in:
Gerald Monaco 2020-04-02 00:22:04 -07:00 committed by GitHub
parent 5db180b221
commit 139da5ade2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -164,9 +164,13 @@ function createLoadableComponent(loadFn, options) {
const context = React.useContext(LoadableContext) const context = React.useContext(LoadableContext)
const state = useSubscription(subscription) const state = useSubscription(subscription)
React.useImperativeHandle(ref, () => ({ React.useImperativeHandle(
ref,
() => ({
retry: subscription.retry, retry: subscription.retry,
})) }),
[]
)
if (context && Array.isArray(opts.modules)) { if (context && Array.isArray(opts.modules)) {
opts.modules.forEach(moduleName => { opts.modules.forEach(moduleName => {
@ -174,6 +178,7 @@ function createLoadableComponent(loadFn, options) {
}) })
} }
return React.useMemo(() => {
if (state.loading || state.error) { if (state.loading || state.error) {
return React.createElement(opts.loading, { return React.createElement(opts.loading, {
isLoading: state.loading, isLoading: state.loading,
@ -187,6 +192,7 @@ function createLoadableComponent(loadFn, options) {
} else { } else {
return null return null
} }
}, [props, state])
} }
LoadableComponent.preload = () => init() LoadableComponent.preload = () => init()
@ -243,12 +249,12 @@ class LoadableSubscription {
this._res.promise this._res.promise
.then(() => { .then(() => {
this._update() this._update({})
this._clearTimeouts() this._clearTimeouts()
}) })
// eslint-disable-next-line handle-callback-err // eslint-disable-next-line handle-callback-err
.catch(err => { .catch(err => {
this._update() this._update({})
this._clearTimeouts() this._clearTimeouts()
}) })
this._update({}) this._update({})
@ -257,6 +263,9 @@ class LoadableSubscription {
_update(partial) { _update(partial) {
this._state = { this._state = {
...this._state, ...this._state,
error: this._res.error,
loaded: this._res.loaded,
loading: this._res.loading,
...partial, ...partial,
} }
this._callbacks.forEach(callback => callback()) this._callbacks.forEach(callback => callback())
@ -268,12 +277,7 @@ class LoadableSubscription {
} }
getCurrentValue() { getCurrentValue() {
return { return this._state
...this._state,
error: this._res.error,
loaded: this._res.loaded,
loading: this._res.loading,
}
} }
subscribe(callback) { subscribe(callback) {