Skip to Content
SWR 2.0 is out! Read more →
DocumentationGetting Started

Getting Started

https://google.com/da;djaldhksagfugsufgasuyfgyuasgfuasgdjasbdjasdjkasfuydfasyrdyafsdygasjdgasgdsafgdhjfasgjdfsahjdfsahjgdasgdjkasgdkjasgdkjasgdkagdkjasgdkjagdkjagdkagdkagdkjagdkagdkagdkagda

  • foo
    • bar
    • baz
      • qux
      • qwe
        1. he
        2. be
          1. wo
          2. be da
            • da
            • ba
111 111
content line 1 some more content
222 222
content line 2 some more content
333 333
content line 3 some more content

Step 1

Step 1.1

Step 1.2

Step 2

Step 2.1

Step 2.2

Development

Install Dependencies

Run pnpm install in the project root directory.

Lint

Lint ESLint

run pnpm lint

Lint Prettier

run pnpm lint:prettier --write to format the entire project.

Test

Run pnpm test

CSS
html {
  background: red;
}
GraphQL
type Character {
  name: String
}
Python
# type Character {
class Character:
  # name: String
  def name(self):
    return self._name
C#
// type Character {
public class Character {
  // name: String
  public String Name { get; }
}

__esModule

Docs theme box-decoration-theme: clone can create confusing output over line breaks


Link

Foo "I am from export const"

Bar code

Latex latex2latex^2

Da
MaChina

Qux someVal

My file is <MyFile />
x2x^2 12x2\int_1^2x^2

Inside your React project directory, run the following:

npm i swr __esModule

Quick Start latexlatex

For normal RESTful APIs with JSON data, first you need to create a fetcher function, which is just a wrapper of the native fetch:

const fetcher = (...args) => fetch(...args).then(res => res.json())
💡

If you want to use GraphQL API or libs like Axios, you can create your own fetcher function. Check here for more examples.

    • schema.graphql
    • schema.graphql
    • schema.graphql
      • schema.graphql
Renders properly
content
Renders on next line
content

Then you can import useSWR and start using it inside any function components:

import useSWR from 'swr'
 
function Profile() {
  const { data, error } = useSWR('/api/user/123', fetcher)
 
  if (error) return <div>failed to load</div>
  if (!data) return <div>loading...</div>
 
  // render data
  return <div>hello {data.name}!</div>
}

Normally, there’re 3 possible states of a request: “loading”, “ready”, or “error”. You can use the value of data and error to determine the current state of the request, and return the corresponding UI.

Make It Reusable

Here’s a JavaScript expression: const a = 1 + 2.

When building a web app, you might need to reuse the data in many places of the UI. It is incredibly easy to create reusable data hooks on top of SWR:

function useUser(id) {
  const { data, error } = useSWR(`/api/user/${id}`, fetcher)
 
  return {
    user: data,
    isLoading: !error && !data,
    isError: error
  }
}

And use it in your components:

function Avatar({ id }) {
  const { user, isLoading, isError } = useUser(id)
 
  if (isLoading) return <Spinner />
  if (isError) return <Error />
  return <img src={user.avatar} />
}

By adopting this pattern, you can forget about fetching data in the imperative way: start the request, update the loading state, and return the final result. Instead, your code is more declarative: you just need to specify what data is used by the component.

Example

In a real-world example, our website shows a navbar and the content, both depend on user:

Traditionally, we fetch data once using useEffect in the top level component, and pass it to child components via props (notice that we don’t handle error state for now):

// page component
 
function Page() {
  const [user, setUser] = useState(null)
 
  // fetch data
  useEffect(() => {
    fetch('/api/user')
      .then(res => res.json())
      .then(data => setUser(data))
  }, [])
 
  // global loading state
  if (!user) return <Spinner />
 
  return (
    <div>
      <Navbar user={user} />
      <Content user={user} />
    </div>
  )
}
 
// child components
 
function Navbar({ user }) {
  return (
    <div>
      ...
      <Avatar user={user} />
    </div>
  )
}
 
function Content({ user }) {
  return <h1>Welcome back, {user.name}</h1>
}
 
function Avatar({ user }) {
  return <img src={user.avatar} alt={user.name} />
}

Usually, we need to keep all the data fetching in the top level component and add props to every component deep down the tree. The code will become harder to maintain if we add more data dependency to the page.

Although we can avoid passing props using Context, there’s still the dynamic content problem: components inside the page content can be dynamic, and the top level component might not know what data will be needed by its child components.

SWR solves the problem perfectly. With the useUser hook we just created, the code can be refactored to:

// page component
function Page() {
  return (
    <div>
      <Navbar />
      <Content />
    </div>
  )
}
 
// child components
function Navbar() {
  return (
    <div>
      ...
      <Avatar />
    </div>
  )
}
 
function Content() {
  const { user, isLoading } = useUser()
  if (isLoading) return <Spinner />
  return <h1>Welcome back, {user.name}</h1>
}
 
function Avatar() {
  const { user, isLoading } = useUser()
  if (isLoading) return <Spinner />
  return <img src={user.avatar} alt={user.name} />
}

Data is now bound to the components which need the data, and all components are independent to each other. All the parent components don’t need to know anything about the data or passing data around. They just render. The code is much simpler and easier to maintain now.

The most beautiful thing is that there will be only 1 request sent to the API, because they use the same SWR key and the request is deduped, cached and shared automatically.

Also, the application now has the ability to refetch the data on user focus or network reconnect! That means, when the user’s laptop wakes from sleep or they switch between browser tabs, the data will be refreshed automatically.

Last updated on