React Hooks用计时器管理API调用



我需要做一个返回URL的fetch api调用,使用返回的URL进行操作,然后在60秒后刷新URL。这是我没有钩子可以舒适地实现的目标,但是我想要一个钩子解决方案。

重要:我不想将其重构为多个组件,也不是为计时器或API调用创建自定义挂钩。

编辑:问题是 - 这是在钩环境中处理计时器的正确方法吗?有更好的方法吗?

import React, { useState, useEffect } from 'react'
import { post } from 'utils/requests'
const FetchUrl = ({ id }) => {
  const [url, setUrl] = useState('')
  let [count, setCount] = useState(0)
  const tick = () => {
    let newCount = count < 60 ? count + 1 : 0
    setCount(newCount)
  }
  useEffect(() => {
    const timer = setInterval(() => tick(), 1000)
    if (count === 0) {
      post('/api/return-url/', { id: [id] })
        .then(res => {
          if (res && res.content) {
            setUrl(res.content.url)
          }
        })
    }
    return () => clearInterval(timer)
  })
  return url ? (
    <span className="btn sm">
      <a href={url} target="_blank" rel="noopener noreferrer">go</a>
    </span>
  ) : null
}
export default FetchUrl

查看是否对您有用。

我将其分为2 useEffect()。一个在第一播放(类似于componentDidMount(之后运行以设置计时器。和其他基于计数值进行API调用。

注意:我使用了ref,以便我可以将一个API调用与另一个呼叫区分开并在其中添加一个数字。

请参阅下面的摘要:

const FetchUrl = ({ id }) => {
  const [url, setUrl] = React.useState('');
  const [count, setCount] = React.useState(0);
  const someRef = React.useRef(0);
  const tick = () => {
    //let newCount = count < 60 ? count + 1 : 0
    setCount((prevState) => prevState < 60 ? prevState +1 : 0);
  }
  
  function mockAPI() {
    return new Promise((resolve,request) => {
      someRef.current = someRef.current + 1;
      setTimeout(()=>resolve('newData from API call ' + someRef.current),1000);
    });
  }
  React.useEffect(() => {
    const timer = setInterval(() => tick(), 100);
    return () => clearInterval(timer);
  });
  
  React.useEffect(() => {
    if (count === 0) {
      /*post('/api/return-url/', { id: [id] })
        .then(res => {
          if (res && res.content) {
            setUrl(res.content.url)
          }
        })
      */
      mockAPI().then((data) => setUrl(data));
    }
  },[count]);
  return url ? (
    <span className="btn sm">
      <div>{count}</div>
      <a href={url} target="_blank" rel="noopener noreferrer">{url}</a>
    </span>
  ) : null
}
ReactDOM.render(<FetchUrl/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>

相关内容

  • 没有找到相关文章