1
0
Fork 0
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:
Shaleen Jain 2018-01-26 21:37:17 +05:30 committed by Tim Neutkens
parent 8dd8e200e0
commit c40f184a6a
2 changed files with 39 additions and 27 deletions

View file

@ -5,6 +5,34 @@ import { execOnce, warn } from 'next/dist/lib/utils'
import exact from 'prop-types-exact'
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
export default class LinkWithData extends Link {
// re defined Link propTypes to add `withData`
@ -33,32 +61,16 @@ export default class LinkWithData extends Link {
// our custom prefetch method
async prefetch () {
// if the prefetch prop is not defined or
// we're running server side do nothing
// if the prefetch prop is not defined do nothing
if (!this.props.prefetch) return
if (typeof window === 'undefined') return
const url =
typeof this.props.href !== 'string'
? format(this.props.href)
: this.props.href
const { pathname } = window.location
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)
// if withData prop is defined
// prefetch with data
// otherwise just prefetch the page
if (this.props.withData) {
prefetch(this.props.href)
} else {
super.prefetch()
}
}
}

View file

@ -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
export default () => (
@ -16,8 +16,8 @@ export default () => (
</Link>
</li>
<li>
<Link href='/article?id=3' prefetch withData>
<a>Article 3</a>
<Link href='/article?id=3' >
<a onMouseOver={e => prefetch('/article?id=3')} >Article 3</a>
</Link>
</li>
</ul>