Skip to content
SWR 2.0 is out! Read more →
Docs
Getting Started

Getting Started

https://google.com/da;djaldhksagfugsufgasuyfgyuasgfuasgdjasbdjasdjkasfuydfasyrdyafsdygasjdgasgdsafgdhjfasgjdfsahjdfsahjgdasgdjkasgdkjasgdkjasgdkagdkjasgdkjagdkjagdkagdkagdkjagdkagdkagdkagda

__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.