Skip to content

Commit

Permalink
Improvements (#130)
Browse files Browse the repository at this point in the history
* fix #128

* allow function returning args

* replace badges; adjust options

* if there's no fetcher, we can ignore the error. #123

* change splice to swap delete
  • Loading branch information
shuding authored and pacocoursey committed Nov 18, 2019
1 parent 4811770 commit 813da18
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 20 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

<p align="center">
<a aria-label="ZEIT logo" href="https://github.com/zeit">
<img src="https://img.shields.io/badge/MADE%20BY%20ZEIT-000000.svg?logo=ZEIT&labelColor=000000&logoWidth=12">
<img src="https://badgen.net/badge/icon/MADE%20BY%20ZEIT?icon=zeit&label&color=black&labelColor=black">
</a>
<a aria-label="NPM version" href="https://www.npmjs.com/package/swr">
<img alt="" src="https://img.shields.io/npm/v/swr">
<img alt="" src="https://badgen.net/npm/v/swr">
</a>
<a aria-label="Package size" href="https://bundlephobia.com/result?p=swr">
<img alt="" src="https://img.shields.io/bundlephobia/minzip/swr">
<img alt="" src="https://badgen.net/bundlephobia/minzip/swr">
</a>
<a aria-label="License" href="https://github.com/zeit/swr/blob/master/LICENSE">
<img alt="" src="https://img.shields.io/npm/l/swr">
<img alt="" src="https://badgen.net/npm/license/swr">
</a>
</p>

Expand Down Expand Up @@ -107,6 +107,7 @@ const { data, error, isValidating, revalidate } = useSWR(key, fetcher, options)

- `suspense = false`: enable React Suspense mode [(details)](#suspense-mode)
- `fetcher = undefined`: the default fetcher function
- `initialData`: initial data to be returned (note: This is per-hook)
- `revalidateOnFocus = true`: auto revalidate when window gets focused
- `refreshInterval = 0`: polling interval (disabled by default)
- `refreshWhenHidden = false`: polling when the window is invisible (if `refreshInterval` is enabled)
Expand All @@ -119,7 +120,6 @@ const { data, error, isValidating, revalidate } = useSWR(key, fetcher, options)
- `onSuccess`: callback function when a request finishs successfully
- `onError`: callback function when a request returns an error
- `onErrorRetry`: handler for [error retry](#error-retries)
- `initialData`: initial data to be returned (note: This is per-hook)

When under a slow network (2G, <= 70Kbps), `errorRetryInterval` will be 10s, and
`loadingTimeout` will be 5s by default.
Expand Down
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export interface RevalidateOptionInterface {
dedupe?: boolean
}

type keyFunction = () => string
export type keyInterface = string | keyFunction | any[] | null
type keyFunction = () => string | any[] | null
export type keyInterface = keyFunction | string | any[] | null
export type updaterInterface<Data = any, Error = any> = (
shouldRevalidate?: boolean,
data?: Data,
Expand Down
38 changes: 25 additions & 13 deletions src/use-swr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,26 @@ const useIsomorphicLayoutEffect = IS_SERVER ? useEffect : useLayoutEffect

// TODO: introduce namepsace for the cache
const getErrorKey = key => (key ? 'err@' + key : '')
const getKeyArgs = _key => {
let key: string
const getKeyArgs = key => {
let args = null
if (typeof _key === 'function') {
if (typeof key === 'function') {
try {
key = _key()
key = key()
} catch (err) {
// dependencies not ready
key = ''
}
} else if (Array.isArray(_key)) {
}

if (Array.isArray(key)) {
// args array
key = hash(_key)
args = _key
args = key
key = hash(key)
} else {
// convert null to ''
key = String(_key || '')
key = String(key || '')
}

return [key, args]
}

Expand Down Expand Up @@ -187,7 +189,7 @@ function useSWR<Data = any, Error = any>(
async (
revalidateOpts: RevalidateOptionInterface = {}
): Promise<boolean> => {
if (!key) return false
if (!key || !fn) return false
if (unmountedRef.current) return false
revalidateOpts = Object.assign({ dedupe: false }, revalidateOpts)

Expand Down Expand Up @@ -441,12 +443,22 @@ function useSWR<Data = any, Error = any>(
unmountedRef.current = true

if (onFocus && FOCUS_REVALIDATORS[key]) {
const index = FOCUS_REVALIDATORS[key].indexOf(onFocus)
if (index >= 0) FOCUS_REVALIDATORS[key].splice(index, 1)
const revalidators = FOCUS_REVALIDATORS[key]
const index = revalidators.indexOf(onFocus)
if (index >= 0) {
// 10x faster than splice
// https://jsperf.com/array-remove-by-index
revalidators[index] = revalidators[revalidators.length - 1]
revalidators.pop()
}
}
if (CACHE_REVALIDATORS[key]) {
const index = CACHE_REVALIDATORS[key].indexOf(onUpdate)
if (index >= 0) CACHE_REVALIDATORS[key].splice(index, 1)
const revalidators = CACHE_REVALIDATORS[key]
const index = revalidators.indexOf(onUpdate)
if (index >= 0) {
revalidators[index] = revalidators[revalidators.length - 1]
revalidators.pop()
}
}

if (timeout !== null) {
Expand Down
19 changes: 19 additions & 0 deletions test/use-swr.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,25 @@ describe('useSWR', () => {
)
})

it('should accept function returning args', async () => {
const obj = { v: 'hello' }
const arr = ['world']

function Page() {
const { data } = useSWR(
() => ['args-3', obj, arr],
(a, b, c) => a + b.v + c[0]
)

return <div>{data}</div>
}

const { container } = render(<Page />)

await waitForDomChange({ container })
expect(container.textContent).toMatchInlineSnapshot(`"args-3helloworld"`)
})

it('should accept initial data', async () => {
function Page() {
const { data } = useSWR('initial-data-1', () => 'SWR', {
Expand Down

0 comments on commit 813da18

Please sign in to comment.