Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应挂钩。周期运行效应_Javascript_Reactjs_React Hooks_Setinterval_Use Effect - Fatal编程技术网

Javascript 反应挂钩。周期运行效应

Javascript 反应挂钩。周期运行效应,javascript,reactjs,react-hooks,setinterval,use-effect,Javascript,Reactjs,React Hooks,Setinterval,Use Effect,我需要定期获取数据并将其更新到屏幕上。 我有以下代码: const [temperature, setTemperature] = useState(); useEffect(() => { fetch("urlToWeatherData") .then(function(response) { if (response.status !== 200) { console.log( "Looks like there was a problem

我需要定期获取数据并将其更新到屏幕上。 我有以下代码:

const [temperature, setTemperature] = useState();

useEffect(() => {

fetch("urlToWeatherData")
  .then(function(response) {
     if (response.status !== 200) {
      console.log(
        "Looks like there was a problem. Status Code: " + response.status
      );
      return;
    response.json().then(function(data) {
     console.log(data[0].temperature);
     setTemperature(data[0].temperature);

    });
  })
  .catch(function(err) {
    console.log("Fetch Error :-S", err);
  });
 }, []  );
那么,在这个例子中,是否有任何简洁的方法可以每15秒运行一次呢?
谢谢

将其包装成一个间隔,并且不要忘记在组件卸载时返回一个拆卸函数来取消间隔:

useEffect(() => {
  const id = setInterval(() => 
    fetch("urlToWeatherData")
      .then(function(response) {
         if (response.status !== 200) {
          console.log(
            "Looks like there was a problem. Status Code: " + response.status
          );
          return;
        response.json().then(function(data) {
         console.log(data[0].temperature);
         setTemperature(data[0].temperature);
        });
      })
      .catch(function(err) {
        console.log("Fetch Error :-S", err);
      });
  ), 15000);

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

为了提供一种不同的方法,您可以定义一个自定义挂钩,用于将此功能提取到可重用函数中:

const useInterval = (callback, interval, immediate) => {
  const ref = useRef();

  // keep reference to callback without restarting the interval
  useEffect(() => {
    ref.current = callback;
  }, [callback]);

  useEffect(() => {
    // when this flag is set, closure is stale
    let cancelled = false;

    // wrap callback to pass isCancelled getter as an argument
    const fn = () => {
      ref.current(() => cancelled);
    };

    // set interval and run immediately if requested
    const id = setInterval(fn, interval);
    if (immediate) fn();

    // define cleanup logic that runs
    // when component is unmounting
    // or when or interval or immediate have changed
    return () => {
      cancelled = true;
      clearInterval(id);
    };
  }, [interval, immediate]);
};
然后你可以像这样使用钩子:

const [temperature, setTemperature] = useState();

useInterval(async (isCancelled) => {
  try {
    const response = await fetch('urlToWeatherData');
    // check for cancellation after each await
    // to prevent further action on a stale closure
    if (isCancelled()) return;

    if (response.status !== 200) {
      // throw here to handle errors in catch block
      throw new Error(response.statusText);
    }

    const [{ temperature }] = await response.json();
    if (isCancelled()) return;

    console.log(temperature);
    setTemperature(temperature);
  } catch (err) {
    console.log('Fetch Error:', err);
  }
}, 15000, true);

如果通过检查
isCancelled()
卸载组件,我们可以防止回调调用
setTemperature()
。对于回调依赖于有状态变量时的
useInterval()
更一般的用例,您应该更喜欢或至少使用。

只是一个补充说明,如果您想在初始化后立即运行它,而不是15秒,只需命名arrow函数,将引用传递给
setInterval()
然后在返回拆卸前立即呼叫。谢谢大家!我将它包装在一个函数中,然后只调用了两次,比如:
getData()设置间隔(getData,15000)现在它似乎完全按照它应该的方式工作。