Home > Software design >  setState placed in an event listener not updating the state correctly
setState placed in an event listener not updating the state correctly

Time:10-26

I am having a weird issue where a setState is not setting the state correctly and I can't figure out why is this happening. I have a component that has a useState batch property and I have created an event listener in the useEffect that listens for the test event and adds it to the batch state property.

Unfortunately, it seems that even if I emit a couple of test events, they don't get saved in the batch property correctly. I imagine the fact that the setState is in an event listener has something to do with this

const AnalyticsProvider= ({ children }) => {
    const [batch, setBatch] = useState([]);

    useEffect(() => {
        Doorman.test((event) => setBatch((previousBatch) => [...previousBatch, event]));
    }, [])
}

CodePudding user response:

The use effect you have there will only run on the first render. Thus making the listener only run on the first render. Move it outside of the useEffect and see if that works.

CodePudding user response:

You need to find a way to clean up the listner for the component to rerender. Also the useEffect needs to fire more often than mount.

Probably something like this:

useEffect(() => {
  Doorman.test((event) => setShouldShowUpgradeDialog((previousBatch) => 
    [...previousBatch, event]));
  return () => Remove Doorman.test // This is pseudocode
))

You likely want to create or use lodash's debounce function to limit this.

  • Related