I have an input. On every change to the input, I want to call an API.
Here's a simplified version of the code:
// updated by input
const [urlText, setUrlText] = useState("");
const fetcher = useFetcher();
useEffect(() => {
if (urlText === "" || !fetcher) return;
fetcher.load(`/api/preview?url=${urlText}`);
}, [urlText]);
The issue is, when I put urlText
inside of the dependencies array, there is an infinite rendering loop, and React claims the issue is I might be updating state inside of the useEffect
. However, as far as I can tell, I'm not updating any state inside of the hook, so I'm not sure why an infinite re-render is happening.
Any thoughts?
The fuller version code is:
Note: The bug still happens without the debounce, or the useMemo
, all of that stuff is roughly irrelevant.
export default function () {
const { code, higlightedCode } = useLoaderData<API>();
const [urlText, setUrlText] = useState("");
const url = useMemo(() => getURL(prefixWithHttps(urlText)), [urlText]);
const debouncedUrl = useDebounce(url, 250);
const fetcher = useFetcher();
useEffect(() => {
if (url === null || !fetcher) return;
fetcher.load(`/api/preview?url=${encodeURIComponent(url.toString())}`);
}, [debouncedUrl]);
return (
<input
type="text"
placeholder="Paste URL"
className={clsx(
"w-full rounded-sm bg-gray-800 text-white text-center placeholder:text-white"
//"placeholder:text-left text-left"
)}
value={urlText}
onChange={(e) => setUrlText(e.target.value)}
></input>
);
}
CodePudding user response:
You might by setting state in useFetcher hook, please check code of load method from useFetcher.
CodePudding user response:
I think it's because useEffect will loop until there is something in urlText, even if you put an "if" to check if it's empty or not.
It's a possibility