【问题标题】:Call API Every X Seconds in React Function Component在 React 函数组件中每 X 秒调用一次 API
【发布时间】:2020-03-27 12:21:20
【问题描述】:

我有以下反应类组件每 10 秒调用一次 API。它的工作没有问题。

class Alerts extends Component {
  constructor() {
    this.state = {
      alerts: {},
    }
  }

  componentDidMount() {
    this.getAlerts()
    this.timerId = setInterval(() => this.getAlerts(), 10000)
  }

  componentWillUnmount() {
    clearInterval(this.timerId)
  }

  getAlerts() {
    fetch(this.getEndpoint('api/alerts/all"))
        .then(result => result.json())
        .then(result => this.setState({ alerts: result }))
  }

  render() {
    return (
      <>
        <ListAlerts alerts={this.state.alerts} />
      </>
    )
  }
}

我正在尝试将其隐藏为反应功能组件。这是我目前的尝试。

const Alerts = () => {

    const [alerts, setAlerts] = useState([])

    useEffect(() => {
        getAlerts()
        setInterval(() => getAlerts(), 10000)
    }, [])

    getAlerts() {
        fetch(this.getEndpoint('api/alerts/all"))
            .then(result => result.json())
            .then(result => setAlerts(result)
    }

    return (
      <>
        <ListAlerts alerts={alerts} />
      </>
    )
}

请有人帮我完成这个例子吗? useEffect 是正确的用法还是有更好的选择?

任何帮助将不胜感激

【问题讨论】:

    标签: reactjs react-native react-component react-context react-functional-component


    【解决方案1】:

    这里的一个问题是this.getEndpoint 不能在函数组件中工作。原来的Alerts 类组件似乎缺少一些代码,因为必须在某个地方实现。

    另一个问题是间隔没有被清理 - 你应该从效果体返回一个清理函数来清除计时器。

    最后,没有理由在每次渲染时重新定义getAlerts,在效果体内部定义一次会更好。

    在清理了一些缺失的括号等之后,我的最终实现将如下所示:

    function getEndpoint(path) {
       return ...; // finish implementing this
    }
    
    
    const Alerts = () => {
    
        const [alerts, setAlerts] = useState([])
    
        useEffect(() => {
            function getAlerts() {
              fetch(getEndpoint('api/alerts/all'))
                .then(result => result.json())
                .then(result => setAlerts(result))
            }
            getAlerts()
            const interval = setInterval(() => getAlerts(), 10000)
            return () => {
              clearInterval(interval);
            }
        }, [])
    
        return (
          <>
            <ListAlerts alerts={alerts} />
          </>
        )
    }
    

    【讨论】:

    • 正是我需要的:-)
    【解决方案2】:

    我找到了 Dan Abramov 的 this blog,它解释了解决此问题的 useInterval 钩子的想法。 你可以这样使用它:

    function Counter() {
      useInterval(() => {
        callMyApi()
      }, 1000);
    }
    

    并以这种方式声明 useInterval 钩子:

    import React, { useState, useEffect, useRef } from 'react';
    
    function useInterval(callback, delay) {
      const savedCallback = useRef();
    
      // Remember the latest callback.
      useEffect(() => {
        savedCallback.current = callback;
      }, [callback]);
    
      // Set up the interval.
      useEffect(() => {
        function tick() {
          savedCallback.current();
        }
        if (delay !== null) {
          let id = setInterval(tick, delay);
          return () => clearInterval(id);
        }
      }, [delay]);
    }
    

    希望它对某人有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-28
      • 2019-04-08
      • 2020-12-07
      • 2021-12-22
      • 1970-01-01
      • 2012-03-14
      相关资源
      最近更新 更多