mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Extend with-data-prefetch to handle advanced use cases (#3525)
This commit is contained in:
parent
8dd8e200e0
commit
c40f184a6a
|
@ -5,6 +5,34 @@ import { execOnce, warn } from 'next/dist/lib/utils'
|
||||||
import exact from 'prop-types-exact'
|
import exact from 'prop-types-exact'
|
||||||
import { format, resolve, parse } from 'url'
|
import { format, resolve, parse } from 'url'
|
||||||
|
|
||||||
|
export const prefetch = async (href) => {
|
||||||
|
// if we're running server side do nothing
|
||||||
|
if (typeof window === 'undefined') return
|
||||||
|
|
||||||
|
const url =
|
||||||
|
typeof href !== 'string'
|
||||||
|
? format(href)
|
||||||
|
: href
|
||||||
|
|
||||||
|
const { pathname } = window.location
|
||||||
|
|
||||||
|
const parsedHref = resolve(pathname, url)
|
||||||
|
|
||||||
|
const { query } =
|
||||||
|
typeof href !== 'string'
|
||||||
|
? href
|
||||||
|
: parse(url, true)
|
||||||
|
|
||||||
|
const Component = await Router.prefetch(parsedHref)
|
||||||
|
|
||||||
|
// if Component exists and has getInitialProps
|
||||||
|
// fetch the component props (the component should save it in cache)
|
||||||
|
if (Component && Component.getInitialProps) {
|
||||||
|
const ctx = { pathname: href, query, isVirtualCall: true }
|
||||||
|
await Component.getInitialProps(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// extend default next/link to customize the prefetch behaviour
|
// extend default next/link to customize the prefetch behaviour
|
||||||
export default class LinkWithData extends Link {
|
export default class LinkWithData extends Link {
|
||||||
// re defined Link propTypes to add `withData`
|
// re defined Link propTypes to add `withData`
|
||||||
|
@ -33,32 +61,16 @@ export default class LinkWithData extends Link {
|
||||||
|
|
||||||
// our custom prefetch method
|
// our custom prefetch method
|
||||||
async prefetch () {
|
async prefetch () {
|
||||||
// if the prefetch prop is not defined or
|
// if the prefetch prop is not defined do nothing
|
||||||
// we're running server side do nothing
|
|
||||||
if (!this.props.prefetch) return
|
if (!this.props.prefetch) return
|
||||||
if (typeof window === 'undefined') return
|
|
||||||
|
|
||||||
const url =
|
// if withData prop is defined
|
||||||
typeof this.props.href !== 'string'
|
// prefetch with data
|
||||||
? format(this.props.href)
|
// otherwise just prefetch the page
|
||||||
: this.props.href
|
if (this.props.withData) {
|
||||||
|
prefetch(this.props.href)
|
||||||
const { pathname } = window.location
|
} else {
|
||||||
|
super.prefetch()
|
||||||
const href = resolve(pathname, url)
|
|
||||||
|
|
||||||
const { query } =
|
|
||||||
typeof this.props.href !== 'string'
|
|
||||||
? this.props.href
|
|
||||||
: parse(url, true)
|
|
||||||
|
|
||||||
const Component = await Router.prefetch(href)
|
|
||||||
|
|
||||||
// if withData prop is defined, Component exists and has getInitialProps
|
|
||||||
// fetch the component props (the component should save it in cache)
|
|
||||||
if (this.props.withData && Component && Component.getInitialProps) {
|
|
||||||
const ctx = { pathname: href, query, isVirtualCall: true }
|
|
||||||
await Component.getInitialProps(ctx)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Link from '../components/link'
|
import Link, { prefetch } from '../components/link'
|
||||||
|
|
||||||
// we just render a list of 3 articles having 2 with prefetched data
|
// we just render a list of 3 articles having 2 with prefetched data
|
||||||
export default () => (
|
export default () => (
|
||||||
|
@ -16,8 +16,8 @@ export default () => (
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link href='/article?id=3' prefetch withData>
|
<Link href='/article?id=3' >
|
||||||
<a>Article 3</a>
|
<a onMouseOver={e => prefetch('/article?id=3')} >Article 3</a>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
Loading…
Reference in a new issue