为什么useFetcher会导致重新渲染无限循环?

发布于 2025-02-05 07:42:06 字数 1448 浏览 3 评论 0原文

我有一个输入。在输入的每一个更改中,我想致电API。

这是代码的简化版本:

  // updated by input
  const [urlText, setUrlText] = useState("");

  const fetcher = useFetcher();

  useEffect(() => {
    if (urlText === "" || !fetcher) return;
    fetcher.load(`/api/preview?url=${urlText}`);
  }, [urlText]);

问题是,当我将urlText放入依赖项数组中时,有一个无限的渲染循环,并且React Soppaim索赔问题是我可能正在更新状态。 使用效果。但是,据我所知,我没有更新钩子内部的任何状态,因此我不确定为什么会发生无限的重新渲染。

有什么想法吗?

代码的完整版本是:

注意:该错误仍然没有访问或usememo ,所有这些内容大致无关。

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>
  );
}

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 of the 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>
  );
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏日落 2025-02-12 07:42:07

您遇到的问题是Fetcher在整个获取过程中都进行了更新。这会导致您的效果重新运行,并且由于您正在调用load,因此它正在重复周期。

您应该检查fetcher.state以查看何时提取。

useEffect(() => {
  // check to see if you haven't fetched yet
  // and we haven't received the data
  if (fetcher.state === 'idle' && !fetcher.data) {
    fetcher.load(url)
  }
}, [url, fetcher.state, fetcher.data])

https://remix.run/docs.run/docs/en/en/en/v1/api/remix#usefetcher

The problem you're having is that fetcher is updated throughout the fetch process. This is causing your effect to re-run, and since you are calling load again, it is repeating the cycle.

You should be checking fetcher.state to see when to fetch.

useEffect(() => {
  // check to see if you haven't fetched yet
  // and we haven't received the data
  if (fetcher.state === 'idle' && !fetcher.data) {
    fetcher.load(url)
  }
}, [url, fetcher.state, fetcher.data])

https://remix.run/docs/en/v1/api/remix#usefetcher

迷鸟归林 2025-02-12 07:42:07

您可以通过在usefetcher挂钩中设置状态,请检查load> load方法的代码 usefetcher 。

You might by setting state in useFetcher hook, please check code of load method from useFetcher.

時窥 2025-02-12 07:42:07

更新:我很傻。 使用的ebouncous返回一个数组。

Update: I'm silly. useDebounce returns an array.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文