【问题标题】:useEffect with time interval runs twice each time带有时间间隔的 useEffect 每次运行两次
【发布时间】:2021-07-09 14:45:30
【问题描述】:

您好,我有一个简单的应用程序,通过使用带有时间间隔的 useEffect 每 3 秒获取一次数据。一切都按需要通过登录控制台购买我看到我的 useEffect 工作了两次,它几乎同时调用了两次 fetchData 函数。我想我的代码中遗漏了一些东西。感谢您的帮助!

       useEffect(() => {
        const interval = setInterval(() => {
          fetchChatData();
        }, 3000);
        return () => clearInterval(interval);
      });

  const fetchChatData = () => {
    setError(null);

    async function fetchData() {
      const request = await axios.get(
        "https://api.jsonbin.io/v3/b/60e6d8a81f8e4a7f2a",
        {
          headers: {
            "Content-Type": "application/json",
            "X-Master-Key":
              "$2b$10$OSaM64SeFaeWQMwrro08kuypgEG7Q",
          },
        }
      );
      const responseData = await request.data;
      chatCtx.setChatData(responseData.record);
    }

    fetchData();
    fetchData().catch((error) => {
      setError(error.response.data.message);
    });
  };

【问题讨论】:

  • 如果您的时间间隔与useState 一起存储,那么它是预期的。在useEffect 中调用setInterval 会导致重绘

标签: reactjs use-effect


【解决方案1】:

您正在使用导致第二次 API 调用的 useEffect 调用 fetchData 函数两次。

删除

fetchData();

之前

fetchData().catch((error) => {
      setError(error.response.data.message);
    });

【讨论】:

    【解决方案2】:

    我会使用 2 个挂钩。第一个钩子在组件加载时执行,因此它的依赖数组设置为空数组[]

    useEffect(()=>{
       // invoke web service to read data into the chatData state variable 
       // when the component loads for the first time
    },[])
    

    然后我有另一个useEffect 钩子将chatData 状态变量设置到它的依赖数组中。在调用 Web 服务之前,此挂钩将等待 3 秒。

    useEffect(()=>{
       // wait 3 seconds
       // invoke web service to read data into the chatData state variable
    },[chatData])
    

    每次在第二个钩子中调用 Web 服务时,钩子中的 chatData 依赖项都会发生变化,这反过来又会导致该钩子无限期地再次触发。

    【讨论】:

    • 方法很好。但他只需要删除 fetchData 中多余的 fetchData。
    【解决方案3】:

    我看不到您所有组件的代码,但 useEffect as is 在每个组件的重新渲染上运行。 Juat 将一个空数组作为useEffect 的第二个参数,它将只运行第一个组件的渲染。比如:

          useEffect(() => {
            const interval = setInterval(() => {
              fetchChatData();
            }, 3000);
            return () => clearInterval(interval);
          }, []);
    

    【讨论】:

      猜你喜欢
      • 2017-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-03
      • 2019-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多