1

So i have a custom hook that may or may not call the API

import { useState, useEffect } from 'react'
import { get } from 'resources/client'

const useAuth = () => {
  const [user, setUser] = useState(null)

  useEffect(() => {
    const lsUserStr = global.localStorage.getItem('auth-user')
    if (lsUserStr) {
      const lsUser = JSON.parse(lsUserStr)
      setUser(lsUser)
    } else {
      refreshUser()
    }
  }, [])

  const refreshUser = async () => {
    const user = await get('auth/me')
    localStorage.setItem('auth-user', JSON.stringify(user))
    setUser(user)
    return user
  }

  return [user, refreshUser]
}

export default useAuth

now, in my main component, i would like to use Suspense, to account on wait

const Component = () => {
  const [user, refreshUser] = useAuth()
  console.log({ user })

  return (

    <Layout>
      <h1>Dashboard</h1>
      <h3>
        Welcome,&nbsp;{user.name}
      </h3>
    </Layout>
  )
}

Edit

Because it's a React Hook that uses useEffect and useState, i can't return a promise from here so that suspense would wait so, in the component, user will always be initialized as null and will only get a value after first render.

I have tried returning a promise from the hook, and it still doesn't work:

const useAuth = () => {
  const [theUser, setUser] = useState(new Promise(() => {}))

  useEffect(() => {
    const lsUserStr = localStorage.getItem('auth-user')
    if (lsUserStr) {
      const lsUser = JSON.parse(lsUserStr)
      setTimeout(() => setUser(lsUser), 2000)
      // setUser(lsUser)
    }
  }, [])
  
  return [user]
}
const Dashboard = () => {
  const [user] = useAuth()
  console.log(user)
  return (
    <Layout>
      <Suspense fallback={<div>loading</div>}>
        <h1>Dashboard</h1>
        <h3>
          Welcome,&nbsp;{user.first_name}&nbsp;{user.last_name}
        </h3>
      </Suspense>
    </Layout>
  )
}

now it doesn't break because user is initially a Promise (object) but it doesn't fallback, it just shows me 'Welcome, ' for two seconds and then fills the data

end Edit

If i try to wrap my component with a Suspense tag, Suspense doesn't know what it's waiting for.

How do other libraries manage to do this?

André Alçada Padez
  • 10,987
  • 24
  • 67
  • 120
  • 1
    Does this answer your question? [How to integrate initial data fetching from a remote API, with React.Suspense?](https://stackoverflow.com/questions/69182057/how-to-integrate-initial-data-fetching-from-a-remote-api-with-react-suspense) – jsejcksn Aug 03 '22 at 03:51

0 Answers0