在 React 函数组件中每隔 X 秒调用 API
Call API Every X Seconds in React Function Component
我有以下反应 class 组件每 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} />
</>
)
}
}
我正在尝试将其转换为 React 功能组件。这是我目前的尝试。
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 是正确的用法还是有更好的选择?
如有任何帮助,我们将不胜感激
这里的一个问题是 this.getEndpoint
在功能组件中不起作用。似乎原始 Alerts
class 组件缺少一些代码,因为必须在某处实现这些代码。
另一个问题是间隔没有被清理——你应该return一个来自效果体的清理函数来清除计时器。
最后,没有理由在每个渲染器上重新定义 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} />
</>
)
}
我找到了 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]);
}
希望对大家有所帮助!
我有以下反应 class 组件每 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} />
</>
)
}
}
我正在尝试将其转换为 React 功能组件。这是我目前的尝试。
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 是正确的用法还是有更好的选择?
如有任何帮助,我们将不胜感激
这里的一个问题是 this.getEndpoint
在功能组件中不起作用。似乎原始 Alerts
class 组件缺少一些代码,因为必须在某处实现这些代码。
另一个问题是间隔没有被清理——你应该return一个来自效果体的清理函数来清除计时器。
最后,没有理由在每个渲染器上重新定义 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} />
</>
)
}
我找到了 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]);
}
希望对大家有所帮助!