parent
84ca9a7b10
commit
b38446717a
1 changed files with 21 additions and 5 deletions
|
@ -2,28 +2,44 @@ import {useContext} from 'react'
|
||||||
import { DataManagerContext } from 'next-server/dist/lib/data-manager-context'
|
import { DataManagerContext } from 'next-server/dist/lib/data-manager-context'
|
||||||
import { RouterContext } from 'next-server/dist/lib/router-context'
|
import { RouterContext } from 'next-server/dist/lib/router-context'
|
||||||
import fetch from 'unfetch'
|
import fetch from 'unfetch'
|
||||||
|
import {stringify} from 'querystring'
|
||||||
|
|
||||||
export function createHook(fetcher: (...args: any) => Promise<any>, options: {key: string}) {
|
type Args = string|number|Array<string|number>
|
||||||
|
|
||||||
|
function generateArgsKey(args: Args[]) {
|
||||||
|
return args.reduce((a: string, b: Args): string => {
|
||||||
|
if (Array.isArray(b)) {
|
||||||
|
return a + generateArgsKey(b)
|
||||||
|
}
|
||||||
|
if (typeof b !== 'string' && typeof b !== 'number') {
|
||||||
|
throw new Error('arguments can only be string or number')
|
||||||
|
}
|
||||||
|
return a + b.toString()
|
||||||
|
}, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createHook(fetcher: (...args: Args[]) => Promise<any>, options: {key: string}) {
|
||||||
if (!options.key) {
|
if (!options.key) {
|
||||||
throw new Error('key not provided to createHook options.')
|
throw new Error('key not provided to createHook options.')
|
||||||
}
|
}
|
||||||
return function useData(...args: any) {
|
return function useData(...args: Array<string|number>) {
|
||||||
const router: import('next-server/lib/router/router').default = useContext(RouterContext)
|
const router: import('next-server/lib/router/router').default = useContext(RouterContext)
|
||||||
const dataManager: import('next-server/lib/data-manager').DataManager = useContext(DataManagerContext)
|
const dataManager: import('next-server/lib/data-manager').DataManager = useContext(DataManagerContext)
|
||||||
const existing = dataManager.get(options.key)
|
const key = `${router.route}${options.key}${generateArgsKey(args)}`
|
||||||
|
const existing = dataManager.get(key)
|
||||||
if (existing && existing.status === 'resolved') {
|
if (existing && existing.status === 'resolved') {
|
||||||
return existing.result
|
return existing.result
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-ignore webpack optimization
|
// @ts-ignore webpack optimization
|
||||||
if (process.browser) {
|
if (process.browser) {
|
||||||
const res = fetch(router.route === '/' ? 'index.json' : router.route + '.json').then((res: any) => res.json()).then((result: any) => {
|
const res = fetch(router.route === '/' ? 'index.json' : router.route + '.json?' + stringify(router.query)).then((res: any) => res.json()).then((result: any) => {
|
||||||
dataManager.overwrite(result)
|
dataManager.overwrite(result)
|
||||||
})
|
})
|
||||||
throw res
|
throw res
|
||||||
} else {
|
} else {
|
||||||
const res = fetcher(...args).then((result) => {
|
const res = fetcher(...args).then((result) => {
|
||||||
dataManager.set(options.key, {
|
dataManager.set(key, {
|
||||||
status: 'resolved',
|
status: 'resolved',
|
||||||
result,
|
result,
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue