Reputation: 1274
I'm new to socket.io
and I'm trying to implement a simple notification.
My problem is that I execute handleClick
function to turn open
to a true value and when socket.on
run its reading incorrect/default value of the open
.
Notification.js
const [open, setOpen] = useState(false);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
if (!open) {
setOpen(true) // set open to true
}
};
useEffect(() => {
socket.on("notification", function (data) {
console.log('SOCKET', open) // idk why this is reading false
})
}, [])
EDIT
Here's my use-case
handleClick
func is where user load his/her notification that will set open
to true and when socket
run it will check if open
is true and dispatch the new notification to existing notification array
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
if (!open) {
setOpen(true) // set open to true
dispatch(getNotifications(params)) // load user notifications
}
};
useEffect(() => {
socket.on("notification", function (data) {
console.log('SOCKET', open) // returning false always
notificationData(data.data)
})
}, [])
const notificationData = ({ sender, message, notif }) => {
setNotifCounter(notifCounter => notifCounter + 1)
setNotification(_.startCase(sender) + ' - ' + message, 'info')
if (open) { // check if user already loaded his/her own notification
dispatch(getNewNotif(notif)) // push to array to avoid duplicate
}
}
Upvotes: 1
Views: 408
Reputation: 202751
An effect with an empty dependency array ([]
) will only run the effect once when the component mounts. Instead, add open
to the dependency array so the effect is triggered on mount and on state update of open
. The issue is that the current value of open
is inclosed in the socket.on
callback, so when state updates the callback needs to re-enclose open
.
const [open, setOpen] = useState(false);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
if (!open) {
setOpen(true) // set open to true
}
};
useEffect(() => {
socket.on("notification", function (data) {
console.log('SOCKET', open);
})
}, [open]) // <-- add open to effect dependency
or you can externally defines the callback
const [open, setOpen] = useState(false);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
if (!open) {
setOpen(true) // set open to true
}
};
const socketOnHandler = data => console.log('SOCKET', open);
useEffect(() => {
socket.on("notification", socketOnHandler) // <-- use callback
}, [])
Upvotes: 1
Reputation: 60
I am not sure this is the proper way. To make it work, when you put socket.on into useEffect without dependency, it looks resolve the issue.
useEffect(() => {
socket.on("notification", function (data) {
console.log('SOCKET', open) // idk why this is reading false
})
});
One more time, I am not sure this way is the proper way.
Upvotes: 0