Home > Back-end >  Is it ok to update state very second?
Is it ok to update state very second?

Time:06-05

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);
  },[])

CodePudding user response:

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

CodePudding user response:

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])
  • Related