首页 > 解决方案 > How to fetch data after a specific Interval with useState, useEffect and useCallback in React with proper dependencies

问题描述

I am trying to fetch Cameras from after a specific interval. Once I fetch all cameras, I set camera in local state but if I try to console.log it I get nothing

const [allCameras, setAllCameras] = useState()

const fetchAllCameras = useCallback(async () => {
    try {
      const res = await getAllCameras();
      if(res.data.status_code === 0 && res.data.data){
        setAllCameras(res.data.data)
      }
    } catch (err) {
      console.error(err);
    }
  }, [])

  const _fetchData = useCallback(async () => {
    fetchAllCameras()

    if(allCameras){
      // Nothing gets logged
      console.log("allCameras", allCameras)
    }

  // If I add allCameras as a dependency it triggers an infinite loop
  }, [fetchAllCameras])

  useEffect(() => {
    _fetchData();
    const intervalID = setInterval(() => {
      _fetchData();
    }, FETCH_INTERVAL * 1000);

    return () => clearInterval(intervalID);
  }, [_fetchData]);  

标签: reactjsreact-nativereact-hooks

解决方案


尝试对您的代码应用一些修复:

  • 每个人都useEffect应该有一个单一的责任。
  • useCallback这里没有必要争论(你想记住什么?你测量了性能问题?)
  • value有一个闭包allCameras,将其移动到 separate useEffect
const [allCameras, setAllCameras] = useState();

const fetchData = () => {
  const fetchAllCameras = async () => {
    try {
      const res = await getAllCameras();
      if (res.data.status_code === 0 && res.data.data) {
        setAllCameras(res.data.data);
      }
    } catch (err) {
      console.error(err);
    }
  };
  fetchAllCameras();
};

// On Mount
useEffect(() => {
  fetchData();
}, []);

// Interval
useEffect(() => {
  const intervalID = setInterval(() => {
    fetchData();
  }, FETCH_INTERVAL * 1000);

  return () => clearInterval(intervalID);
}, []);

// Check state
useEffect(() => {
  console.log(allCameras);
}, [allCameras]);

阅读更多useEffect用例


推荐阅读