繁体   English   中英

清理useffect异步函数中的setTimeout

[英]Cleanup setTimeout inside useffect async function

我正在 React 中开发一个自动保存组件。

我的逻辑是,每当“bestOf”发生变化时,我会使用异步获取函数检查数据是否等于存储在我的数据库中的数据。

  • 如果相等,我将状态设置为已保存
  • 如果不相等,我将状态设置为未保存,然后我想在调用我的handleSave函数之前等待 5 秒

我现在正在尝试清理此超时,以便在对 bestOf 进行多次修改但 useEffect 清理函数在我的情况下不起作用时不多次调用此函数。

这是我对 clearTimeout 的尝试

    useEffect(() => {
        let timeout;
        const compareSave = async () => {
            await fetch(`/api/bestof/get?bestof_id=${bestOf.id}`)
                .then((res) => res.json())
                .then((data) => {
                    if (JSON.stringify(data) === JSON.stringify(bestOf)) {
                        return setSave("saved");
                    } else {
                        setSave("unsaved");
                        timeout = setTimeout(() => {
                            handleSave();
                        }, 5000);
                    }
                })
                .catch((err) => console.log(err));
        };

        compareSave();

        return () => {
            clearTimeout(timeout);
        };
    }, [bestOf]);

这是 AbortController 的另一个尝试

    useEffect(() => {
        const controller = new AbortController();
        const compareSave = async () => {
            await fetch(`/api/bestof/get?bestof_id=${bestOf.id}`, {
                signal: controller.signal,
            })
                .then((res) => res.json())
                .then((data) => {
                    if (JSON.stringify(data) === JSON.stringify(bestOf)) {
                        return setSave("saved");
                    } else {
                        setSave("unsaved");
                        setTimeout(() => {
                            handleSave();
                        }, 5000);
                    }
                })
                .catch((err) => console.log(err));
        };

        compareSave();

        return () => {
            controller.abort()
        };
    }, [bestOf]);

两种解决方案都不起作用,每次修改都会多次执行超时功能。 有什么建议么 ?

经过多次尝试,我终于发现我需要添加一个标志以在超时获取后忽略这些内容,以了解 bestOf 是否发生变化。

否则因为它是异步的,所以在我清除它之后会设置超时。


useEffect(() => {
  let shouldIgnore = false;
  let timeout;

  const compareSave = async () => {
    await fetch(`/api/bestof/get?bestof_id=${bestOf.id}`)
      .then((res) => res.json())
      .then((data) => {
        if (shouldIgnore) {
          return;
        }

        if (JSON.stringify(data) === JSON.stringify(bestOf)) {
          return setSave('saved');
        } else {
          setSave('unsaved');
          timeout = setTimeout(() => {
            handleSave();
          }, 5000);
        }
      })
      .catch((err) => console.log(err));
  };

  compareSave();

  return () => {
    shouldIgnore = true;
    clearTimeout(timeout);
  };
}, [bestOf]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM