每隔X秒在React功能组件中调用API

时间:2019-12-02 20:55:53

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

我有以下反应类组件,每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是否正确使用还是有更好的选择?

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:4)

我发现Dan Abramov的this blog解释了解决这个问题的pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6)钩子的想法。 您可以这样使用它:

useInterval

并以这种方式声明function Counter() { useInterval(() => { callMyApi() }, 1000); } 钩子:

useInterval

希望它对某人有帮助!

答案 1 :(得分:2)

这里的一个问题是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} />
      </>
    )
}