reactjsnotificationsnext.jspubnub

Nextjs Listener with callback executes itself


I have been working on a real-time notification system for my nextjs app. It is working great, and I call it like this in each page:


export default function Bot({user}) {

    startNotifications(user)
}

The function itself looks like this

    const userID = getUserID(user)
    const pubnub = new PubNub({
        subscribeKey: subKey,
        uuid: userID
    });

    const { asPath } = useRouter()
    pubnub.unsubscribeAll();
    pubnub.addListener({
        signal: function(signal) {
            const message = signal.message
            if (message[0] == "bot") {
                Notiflix.Notify.Info(notificationMessage);

                if (check if url is correct here) {
                    callback()
                    return
                }

            }

        }
    })

    pubnub.subscribe({
        channels: ["announcements", userID.toString()],
    });

But when i try to add a callback funtion to change the state, depending on notification like this:

export default function Bot({user}) {

    startNotifications(user, changeState)


    const [value, setValue] = useState(true)

    function changeState(){
      console.log("changing state")
  
      setValue(false)
    }
}

The code works fine, and the state is getting changed, but for some reason the code loops over itself and doubles the number of listeners each notification. In the startNotifications function I even tried to unsubscribe and resubscribe, but that doesn't work either. It looks like this (First notification)

1. Image

And then if I do it a couple more times the 4. Notification looks like this:

2. Image

I am pretty much at the end of trying. I have tried to implement the startNotifications in the same file, but that does the same thing.

If anyone has a solution to this (its probably something very obvious that I don't know) please let me know. Have a great day.


Solution

  • One thing that you are missing is putting the whole startNotifications inside an useEffect hook. Without it, all of this code is executed each time the component rerenders.

    export default function Bot({user}) {
        useEffect(() => startNotifications(user), []);
        
        // rest of the code
    }