Infinite loop - useEffect, router, debounce
Unanswered
Barbary Lion posted this in #help-forum
Barbary LionOP
I've been stuck on this for an hour 💀
Any ideas what is going wrong?
Any ideas what is going wrong?
11 Replies
Barbary LionOP
'use client';
// import { useDebounce } from 'use-debounce';
import { Input } from '../ui/input';
import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
const useDebounce = (value: string, delay: number) => {
console.table([`Debouncing: ${value}`, value]);
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
};
export function SearchBar({ search }: { search?: string }) {
const router = useRouter();
const [text, setText] = useState(search || '');
const query = useDebounce(text, 300);
useEffect(() => {
if (!query || query === '') {
router.push('/add');
} else {
router.push(`/add?search=${query}`);
}
}, [router, query]);
const onChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
setText(e.target.value);
};
return (
<Input
value={text}
placeholder="Search song on Spotify"
id={'search'}
onChange={onChangeHandler}
/>
);
}I've tried my own debounce hook to check if it was an issue with the
useDebounceThe strange thing is that it doesn't always happen, I haven't found bulletproof way to replicate it
âš ï¸ Epilespy warning âš ï¸
Barbary LionOP
Note to myself: Never trust blindly YouTubers 🤦â€â™‚ï¸
Using double useEffect smelled fishy, even more with the router as a dependency... and calling
router.push() inside itMy new code:
'use client';
import { useDebouncedCallback } from 'use-debounce';
import { Input } from '../ui/input';
import { useRouter } from 'next/navigation';
export function SearchBar({ search }: { search?: string }) {
const router = useRouter();
const debounced = useDebouncedCallback((value) => {
router.push(`/add?search=${value}`);
}, 500);
const onChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
debounced(e.target.value);
};
return (
<Input
defaultValue={search}
placeholder="Search song on Spotify"
id={'search'}
onChange={onChangeHandler}
/>
);
}I will add the correct way to URL encode the params
Definitely not perfect.. I'm loosing focus on the input now 😦
but at least I won't have an epillespy
or kill my Vercel bandwidth in a few hours