Skip to content

Instantly share code, notes, and snippets.

@shuding
Created November 27, 2019 07:00
Show Gist options
  • Save shuding/8367e914997ed18945762b13e2a0f649 to your computer and use it in GitHub Desktop.
Save shuding/8367e914997ed18945762b13e2a0f649 to your computer and use it in GitHub Desktop.
SWR
// /swr/project.js
import useSWR, { mutate } from 'swr'

export async function fetchProject (id) {
  mutate(`/api/project/${id}`, fetch(`/api/project/${id}`))
}

export default function useProject (id) {
  // don't pass the fetcher so it won't fetch
  return useSWR(`/api/project/${id}`)
}
// components/project.js
function Project ({ id }) {
  const { data } = useProject(id)
  
  return <>
    {data}
    <button onClick={() => fetchProject(id)}>fetch!</button>
  </>
}
@shuding
Copy link
Author

shuding commented Nov 27, 2019

Some other snippets:

user resource & redirect automatically

// /swr/user.js
export default function useUser(shouldRedirect = false) {
  const swr = useSWR('/api/user', fetcher)

  useEffect(() => {
    if (shouldRedirect && swr.error && swr.error.status === 403) {
      // unauthorized, redirect
      window.location.replace('/login')
    }
  }, [shouldRedirect, swr.error])

  return swr
}

@shuding
Copy link
Author

shuding commented Nov 27, 2019

dependant

// /swr/projects.js

import useUser from './user'

export default function useProjects() {
  const user = useUser().data // can be `undefined`
  return useSWR(() => `/api/projects?uid=${user.id}`, fetcher)
}

@shuding
Copy link
Author

shuding commented Nov 27, 2019

token and logout

// /swr/token.js

const getToken = () => {
  if (isServer) return null
  const match = document.cookie.match(/token=(.+);/)
  if (match) return match[1]
  return null
}

const initialToken = getToken()

export default function useToken() {
  return useSWR('token', getToken(), { initialData: initialToken }
}

So every time you refocus on a window, the token gets reloaded.

// /swr/data.js
import useToken from './token'

export default function useData () {
  return useSWR(['/api/data', useToken()], (url, token) => fetcher(url, { token }))
}

Logout:

import { trigger } from 'swr'

<button onClick={() => {
  // 1. delete token inside document.cookie
  // 2. trigger('token')
}}>logout</button>

@shuding
Copy link
Author

shuding commented Nov 27, 2019

fancy stuff

function useNow (interval) {
  return useSWR('now', () => Date.now(), { refreshInterval: interval, initialData: Date.now() }).data
}

function Clock () {
  const now = useNow(1000)
  return <h1>current time is: {now}</h1>
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment