Page Render loop in next.js 13

I’m tring to make a search bar in NEXT.JS
the SearchBar component uses router to redirect to the search page with a searchParams
the search page uses the searchParams to call an api endpoint to search fo the products and return a JSON object , then set the state inside the search page to the data received.
the fetchHandler is called inside a useEffect hook with an empty dependecy array.

The error: somehow the page stuck in render loop where the useEffect keeps setting the state and the page keep rendering and triggering the useEffect hook !!!,

i’ve checked the api and it is only being called once , there’s only warning about experimental features and a missing key in a list (that was struggling to locate :sweat_smile:) but that didn’t effect anything before .

this pattern is working alright for me in another page, but somehow it’s not in this case,
Am I missing something here or should i look somewhere else?

the search bar:

'use client'
import React from 'react'
import { useState, useRef } from "react";
import {v4 as uuidv4} from 'uuid'; 
import { useRouter } from 'next/navigation';

const SearchBar = () => {
        const router = useRouter();
        const inputRef = useRef();

    const handleChange = (e) => {
        inputRef.current = e.target.value; 
    }
    const handleClick = async (e) => {
        if(!inputRef.current)return;
        // names in the database are all hyphen sepratedlo
        const searchQuery = inputRef.current.trim().split(' ').join('-'); 
        if(!searchQuery)return;
        router.push(`/searchquery?q=${searchQuery}`)
    }
  return (
    <div key={uuidv4()} className='w-72 h-10 bg-white flex-row-between shadow rounded-2xl p-1'>
    <button onClick={e => handleClick(e)} >
        <img src="/assets/icons/search.png" alt="search" className='w-5 h-5 m-1' />
    </button>
    <input type="text" className='w-5/6'
        onChange={ e => handleChange(e)} 
    />
</div> 
  )
}

export default SearchBar

the search page:

'use client';
import {useState, useEffect} from "react";

async function searchquery({searchParams}) {
    const [products, setProducts] = useState([]);
    console.log("🚀 ~ file: page.jsx:7 ~ searchquery ~ products:", products)
    const fetchHandler = async () => {
        try {
            const query = searchParams.q;
            const res = await fetch(`/api/query`,{
                method: 'POST',
                body: JSON.stringify({query: query})
            })
            const data = await res.json()
            if (!res.ok) 
                throw new Error(data.error || 'Something went wrong')
            setProducts(data.products)
            
        } catch (e) {
            setError(e.message)
        }
    }
    
    useEffect(() => {
        fetchHandler()
    }, [])

    return (<div>query</div>)
}

export default searchquery

the api endpoint:

import { connectToDB } from '@utils/database';
import { Product } from '@utils/productModel';
import { NextResponse } from 'next/server';

export async function POST(request) {
    try {
        const res = await request.json();
        const namePart = res.query.split(' ').join('-')
        const query = { name: { $regex: namePart, $options: 'i' } };
        await connectToDB();
        const products = await Product.find(query);
        return NextResponse.json({products})
    } catch (error) {
        console.log(error);
        return NextResponse.json({ error: error.message })
    }

}
  • this seems fine to me and it should not run more than once
  • whats “query” in here?!
  • do you have any rendering method using “map” in your code someplace? you can check that out again
  • try debugging it, use smaller “portion of code” first and then add on to it, to figure out which code block is giving you error

happy coding :slight_smile:

is just a string so i can see if i’m at the right page :sweat_smile:

yeah i’ve searched for every map call in my code and checked all of them and somehow still missed it :smiling_face_with_tear:

i was trying since yesterday, every time i get a new idea i run to test it, the error only appears when i try to set the state,
thank you for you advice , happy coding and have a nice day :v:

sure no problem, you too :slight_smile:

do you have it live somewhere (repl/codesandbox)? that way it will be easier to debug for us as well

unfortunately I don’t know how to deal with replit congfigration and i don’t think it supports next 13 yet with the app router

the solution was deleting the async keyword from the page function

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.