From 4a67acec65fd612781af1270126fde1ed4ae88b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Wed, 6 Feb 2019 00:30:22 +0100 Subject: [PATCH] feat(component): add preload method (#224) Closes #196 --- packages/component/src/createLoadable.js | 7 ++++ packages/component/src/resolvers.js | 3 +- .../src/pages/docs/api-loadable-component.mdx | 20 +++++++++-- website/src/pages/docs/prefetching.mdx | 34 ++++++++++++++++++- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/packages/component/src/createLoadable.js b/packages/component/src/createLoadable.js index 70c75bf58..99af852bf 100644 --- a/packages/component/src/createLoadable.js +++ b/packages/component/src/createLoadable.js @@ -163,6 +163,13 @@ function createLoadable({ resolve = identity, render, onLoad }) { )) + Loadable.preload = props => { + if (typeof window === 'undefined') { + throw new Error('`preload` cannot be called server-side') + } + ctor.requireAsync(props) + } + return Loadable } diff --git a/packages/component/src/resolvers.js b/packages/component/src/resolvers.js index 37f3e56e0..ea8723396 100644 --- a/packages/component/src/resolvers.js +++ b/packages/component/src/resolvers.js @@ -3,8 +3,7 @@ import hoistNonReactStatics from 'hoist-non-react-statics' export function resolveComponent(loadedModule, { Loadable }) { const Component = loadedModule.default || loadedModule hoistNonReactStatics(Loadable, Component, { - prefetch: true, - Prefetch: true, + preload: true, }) return Component } diff --git a/website/src/pages/docs/api-loadable-component.mdx b/website/src/pages/docs/api-loadable-component.mdx index fa8202752..c90f97975 100644 --- a/website/src/pages/docs/api-loadable-component.mdx +++ b/website/src/pages/docs/api-loadable-component.mdx @@ -6,7 +6,7 @@ order: 10 # @loadable/component -## Loadable +## loadable Create a loadable component. @@ -23,7 +23,7 @@ import loadable from '@loadable/component' const OtherComponent = loadable(() => import('./OtherComponent')) ``` -## Lazy +## lazy Create a loadable component "Suspense" ready. @@ -46,6 +46,22 @@ A component created using `loadable` or `lazy`. | `fallback` | Fallback displayed during the loading. | | `...` | Props are forwarded as first argument of `loadFn` | +## LoadableComponent.preload + +Force the loading of a component. + +| Arguments | Description | +| --------- | ---------------------------------- | +| `args` | Props passed to the load function. | + +```js +import loadable from '@loadable/component' + +const OtherComponent = loadable(() => import('./OtherComponent')) + +OtherComponent.preload() +``` + ## loadable.lib Create a loadable library. diff --git a/website/src/pages/docs/prefetching.mdx b/website/src/pages/docs/prefetching.mdx index 33a519bf7..8048ec439 100644 --- a/website/src/pages/docs/prefetching.mdx +++ b/website/src/pages/docs/prefetching.mdx @@ -14,8 +14,40 @@ Most of the time, you want to "prefetch" a component, it means it will be loaded import loadable from '@loadable/component' const OtherComponent = loadable(() => - import(/* webpackPrefetch: true */ './OtherComponent') + import(/* webpackPrefetch: true */ './OtherComponent'), ) ``` > You can extract prefetched resources server-side to add `` in your head. + +## Manually preload a component + +It is possible to _force_ the preload of a component. It has the same effect as if the component is rendered for the first time. + +It can be useful to trigger a `preload` on mouse over: + +```js +import loadable from '@loadable/component' + +const Infos = () => loadable(() => './Infos') + +function App() { + const [show, setShow] = useState(false) + return ( +
+ Infos.preload()} onClick={() => setShow(true)}> + Show Infos + + {show && } +
+ ) +} + +const OtherComponent = loadable(() => + import(/* webpackPrefetch: true */ './OtherComponent'), +) +``` + +> `preload` is not available server-side, you should only call it client-side. If you want to use prefetching server-side, use webpack hints instead. + +> `preload` is aggressive and doesn't take care of network condition and data saving preference of the user. You should call it carefully.