Night Crypt
Night Crypt

Reputation: 41

Next.JS "Rendered more hooks than during the previous render"

I am currently implementing useSWR in order to fetch data from my express and mongo-db backend. I am able to fetch the data successfully from the database no problem. The following is the code i used to achieve this:

```//SWR method for hydration
const fetcher = (...args) => fetch(...args).then(res => res.json())
const { data, error } = useSWR('http://localhost:3000/appi/daily', fetcher)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>```

This is then accessed using:

data.currentInfo.username where username is one of the fields in the collection.

The problem comes in when i try to add this information into a state hook, which then returns the error rendered more hooks than during the previous render.

Removing the line: const[displayNumber] = useState(data.currentInfo.randomString) and any line that uses the state variable displayNumber then fixes the error completely.

I have included the relevant code below:

    const fetcher = (...args) => fetch(...args).then(res => res.json())
    const { data, error } = useSWR('http://localhost:3000/appi/daily', fetcher)
    if (error) return <div>failed to load</div>
    if (!data) return <div>loading...</div>
    
      
    const[displayNumber] = useState(data.currentInfo.randomString)


    //handler function for changing state variable
    function handleNumChange(event){
        console.log(event.target.value);
        setNumber(event.target.value);
      } 


    
    return(
      <div>
        <div>
            <Navbar className="navbar"/>
            <h2>{data.currentInfo.username}</h2>
            <h2>{displayNumber}</h2>

In short im pulling the data with swr, adding this information to a state variable and then displaying it with a h2.

Could anyone enlighten me what is possibly wrong with this approach?

I have searched online for the error which says that it could be caused by useEffect hooks but there isn't any in my code.

Upvotes: 4

Views: 9934

Answers (1)

Stutje
Stutje

Reputation: 844

The error describes you have more hooks than previous render. If you read the react docs, all useState hooks should always be called every render. You can't have a conditional useState while your code has an extra useState bellow following:

if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div> 

That means if there is no error and there is data only then the line const[displayNumber] = useState(data.currentInfo.randomString) will be called.

EDIT: Move it to the top will normally resolve your issue.

    const fetcher = (...args) => fetch(...args).then(res => res.json())
    const { data, error } = useSWR('http://localhost:3000/appi/daily', fetcher)
    //const[displayNumber] = useState(data.currentInfo.randomString) //Needs null checks ofcourse
    //With null checks
    const[displayNumber] = useState((data && data.currentInfo && data.currentInfo.randomString) || undefined)
    //OR
    //const[displayNumber] = useState(data?.currentInfo?.randomString)
    if (error) return <div>failed to load</div>
    if (!data) return <div>loading...</div>

Upvotes: 9

Related Questions