Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Args as key #98

Merged
merged 2 commits into from
Nov 9, 2019
Merged

Args as key #98

merged 2 commits into from
Nov 9, 2019

Conversation

shuding
Copy link
Member

@shuding shuding commented Nov 8, 2019

This is a simple and efficient implementation of a frequently requested feature.

Currently if you want to pass outside args to fetcher (which may change during the lifecycle):

useSWR('key', () => fetcher(...args))

It doesn't work, because the cache is indexed by the key. Which means if your args change, a SWR refetch will not be triggered.

Use Cases

GraphQL:

const personQuery = `
  query Person(id: ID, name: String) {
    person(id: $id, name: $name) {
      id
    }
  }
`

// Reuse same query with different variables.
request(personQuery, { variables: { id: 42 } })
request(personQuery, { variables: { name: "Alice" } })

Multiple params:

const token = useToken()

// SWR will still read the stale data even if `token` changes
const { data } = useSWR('/api/user', url => fetchAPI(url, token))

New API

This implementation doesn't break any existing API or behavior, but allows you to use an array as the key param:

useSWR([...args], fetcher, options)

And arg can be any value, object or even function. SWR will use those args as the key of the cache, and pass them as arguments to fetcher:

fetcher(...args)

Notes

Same as React Hook deps, don't pass anonymous objects/arrays/functions, e.g.:

const x = props.x

// this is wrong, because deps are compared shallowly (===)
useSWR(['hello', {value: x}], fetcher) 

// you can use useMemo
const v = useMemo(() => ({value: x}), [x])
useSWR(['hello', v], fetcher)

// or handle the logic inside fetcher
useSWR(['hello', x], (str, v) => fetcher(str, { value: v }))

Related: #37, #93.
Closes #40, closes #23.

@cryptiklemur
Copy link
Contributor

Closes #37 , would re-implement type-fixes in a separate PR

src/libs/hash.ts Outdated Show resolved Hide resolved
test/use-swr.test.tsx Outdated Show resolved Hide resolved
Co-Authored-By: Paco <34928425+pacocoursey@users.noreply.github.com>
Copy link
Contributor

@pacocoursey pacocoursey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had no idea WeakMap had a good use case before today. Looks good!

@shuding shuding mentioned this pull request Nov 8, 2019
@shuding shuding merged commit 987bbb2 into master Nov 9, 2019
@shuding shuding deleted the args branch November 9, 2019 03:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Using GraphQL doesn't always revalidate Example for urql?
3 participants