Search code examples
reactjsnext.jsswr

UseSWR returning undefined data even when fetcher function returns


When trying to get UseSWR to properly return from a JSON API, I copied and pasted the sample code from their website and switched around the API, but any attempt to access the values in data or error, such as console.log('Data from top level: ' + data) returns only undefined.

const fetcher = (...args) => fetch(...args).then(res => res.json())
const { data, error, isLoading } = useSWR('https://jsonplaceholder.typicode.com/todos/1', fetcher)

Appending .then(json => console.log(json)) to the end of the fetcher function logs the correct value. After searching StackOverflow and finding many answers talking about the fetcher function needing to return its value, I tried this, but const fetcher = (...args) => fetch(...args).then(res => res.json()).then((json) => { return json; }) and variations did not solve the issue.

I've attempted the following useEffect() implementation, but run into the same problem:

  const fetcher = (url) => fetch(url).then(res => res.json()).then(json => console.log(json));
  const { data, error } = useSWR('https://jsonplaceholder.typicode.com/todos/1', fetcher)

  useEffect(() => {
    console.log(`From error:  ${error}`)
    console.log(`Data from top level: ${data}`)
  }, [data, error]
  )

My dependencies are here:

"dependencies": {
    "autoprefixer": "10.4.14",
    "eslint": "8.43.0",
    "eslint-config-next": "13.4.7",
    "next": "13.4.7",
    "postcss": "8.4.24",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "swr": "^2.2.0",
    "tailwindcss": "3.3.2"
  }

Solution

  • You need to await the data by including the isLoading prop returned from useSWR:

    const fetcher = (url) => fetch(url).then(res => res.json()).then(json => console.log(json));
    const { data, isLoading, error } = useSWR('https://jsonplaceholder.typicode.com/todos/1', fetcher)
    
    if (isLoading) {
      return <div>Loading data...</div>
    }