可以非常更新状态第二吗?

发布于 2025-02-04 11:52:52 字数 586 浏览 2 评论 0原文

我试图在购物车中显示物品的数量。我希望计数每秒更新,因此,如果用户从购物车中添加或删除,它将每秒发出该请求并刷新,更新状态,数字将会更改。我只是尝试了这种方法,它可以正常工作,但是我想知道是否可以这样做,或者是否有更好的方法。

 const [update, setUpdate] = useState(0)
  const [data, setData] = useState([])

  let currentUser = 1

  const getData = () => {
      axios.get(`http://localhost:4000/api/userCart/${currentUser}`)
      .then((res) => {
          setData(res.data)
          setUpdate(++update)
      })
  }

  useEffect(() => {
    getData()
  }, [update])

  useEffect(() => {
    setInterval(() => {
      getData()
    }, 1000);
  },[])

I am trying to display the count of items in a cart. I want the count to update every second so if a user adds or deletes from cart it will make that request every second and refresh, updating the state and the number will change. I just tried this method and it works fine, but I'd like to know if it's ok to do or if there is a better way of doing it.

 const [update, setUpdate] = useState(0)
  const [data, setData] = useState([])

  let currentUser = 1

  const getData = () => {
      axios.get(`http://localhost:4000/api/userCart/${currentUser}`)
      .then((res) => {
          setData(res.data)
          setUpdate(++update)
      })
  }

  useEffect(() => {
    getData()
  }, [update])

  useEffect(() => {
    setInterval(() => {
      getData()
    }, 1000);
  },[])

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

相思故 2025-02-11 11:52:52

我认为没关系,您只需要一种清除此间隔的方法,当您销毁该组件时,

const timer = useRef<any>(null);

timer.current = setInterval(() => {
   //your interval code
}, time);

useEffect(()=>{
 return () => {
    clearInterval(timer.current);
  }
},[])

我认为这可能是一个问题,您会遇到一个间隔和效果。

I think thats ok, you need just a way to clear this interval when you destroy the component

const timer = useRef<any>(null);

timer.current = setInterval(() => {
   //your interval code
}, time);

useEffect(()=>{
 return () => {
    clearInterval(timer.current);
  }
},[])

your first useEffect I think can be a problem, you made a interval and a effect that runs every get

没有伤那来痛 2025-02-11 11:52:52

当您想提供像实时的经验时,这是好的。如果这将是生产的,则需要考虑将完成多少请求以及解决和获取数据所需的时间。

Vercel团队中有一个Pacakge SWR,您可以使用 https://swr.vercel.vercel.app/docs/docs/revalidationation ,它获取数据,验证其状态并在可用时提供缓存状态。 如果您想继续自己的实现,请尝试一下

,那么您需要考虑以下方面:

  1. 如果以前的获取完成,则间隔将不关心数据。解决方案:获取数据然后运行SettieMout并通过新的获取清理解决
  2. 。将每个超时保存在参考中,当组件清楚地表明超时
  3. 没有正确的做事方式时,请尝试任何想法,如果它有效,则只需抛光效果,并避免了上述任何副作用:)

要在您共享的代码中考虑当前代码

,getData函数被调用两次,一个来自Interval,然后将requestin Data保留,然后在更新update> UPDATE prop时再次调用。

重构想法可以是这样:

// Out of component body
const UPDATE_INTERVAL = 1000

// In component body
const [update, setUpdate] = useState(0)
const [data, setData] = useState([])
const timer = useRef(null)
useEffect(() => {
  const triggerUpdate = setUpdate((n) => n + 1)
  const getData = () => {
    return axios.get(`http://localhost:4000/api/userCart/${currentUser}`)
  }
  getData()
    .then((res) => {
      setData(res.data)
      timer.current = setTimeout(triggerUpdate, UPDATE_INTERVAL)
    })
    .catch(console.error)
  return () => {
    clearTimeout(timer.current)
  }
}, [update])

It's okay when you want to give a real-time like experience. If this will be on production you need to consider how many request will be done and the time it can take to resolve and get the data.

There's a pacakge SWR from Vercel team which you can use https://swr.vercel.app/docs/revalidation , it fetches data, validates it's state and serves a cached state when available. Give it a try

If you want to continue with your own implementation then you need to take into consideration this:

  1. Intervals will keep fetching data don't caring if previous fetch was completed. Solution: Fetch data then run a setTimeout and resolve with a new fetch
  2. Clean up. Save each timeout in a Ref and when a component unmounts clear that timeOut
  3. There's no correct way of doing stuff, give any idea you have a try and if it works the just polish it and avoid any side effects as the mentioned above : )

To consider in your current code

In the code you shared, the getData function is being invoked twice, one from interval which then keeps requestin data, and again when you update the update prop.

A refactor idea can be this:

// Out of component body
const UPDATE_INTERVAL = 1000

// In component body
const [update, setUpdate] = useState(0)
const [data, setData] = useState([])
const timer = useRef(null)
useEffect(() => {
  const triggerUpdate = setUpdate((n) => n + 1)
  const getData = () => {
    return axios.get(`http://localhost:4000/api/userCart/${currentUser}`)
  }
  getData()
    .then((res) => {
      setData(res.data)
      timer.current = setTimeout(triggerUpdate, UPDATE_INTERVAL)
    })
    .catch(console.error)
  return () => {
    clearTimeout(timer.current)
  }
}, [update])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文