Javascript 套接字通知
我有一个屏幕,接收来自Spring Boot后端的通知,并以铃声的形式显示它们。当删除一个通知时,它会很好地删除它,但当另一个新通知到达时,它会加载我已经删除的通知Javascript 套接字通知,javascript,reactjs,stomp,rsocket-js,Javascript,Reactjs,Stomp,Rsocket Js,我有一个屏幕,接收来自Spring Boot后端的通知,并以铃声的形式显示它们。当删除一个通知时,它会很好地删除它,但当另一个新通知到达时,它会加载我已经删除的通知 import SockJS from 'sockjs-client'; import Stomp from 'stompjs'; // core components const HeaderNotificacions = () => { const [chipData, setChipData] = useState
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
// core components
const HeaderNotificacions = () => {
const [chipData, setChipData] = useState([]); //Hook where I load the notifications that come from the backend >
const historyAlerts = localStorage.getItem('notys')
? JSON.parse(localStorage.getItem('notys'))
: []; if (chipData.length === 0 && historyAlerts.length !== 0) { //I get the notifcations when I reload the browser
setChipData(historyAlerts); }
useEffect(() => {
var sock = new SockJS(
`${process.env.REACT_APP_WEB_SOCKET}mocaConsola/api/notifications`
);
let stompClient = Stomp.over(sock);
sock.onopen = function () {
/* console.log('open'); */
};
stompClient.connect({}, function (frame) {
stompClient.subscribe('/ws/alertNotification', function (greeting) {
if (stompClient !== null) {
stompClient.disconnect();
}
setChipData([
...chipData,
{
key: greeting.headers['message-id'],
label: JSON.parse(greeting.body).content,
},
]);
});
}); }, [chipData]);
localStorage.setItem('notys', JSON.stringify(chipData));
const handleDelete = (chipToDelete) => () => {
const historyAlerts = localStorage.getItem('notys') //function to delete a notification
? JSON.parse(localStorage.getItem('notys'))
: [];
setChipData((chips) =>
chips.filter((chip) => chip.key !== chipToDelete.key)
);
const local = historyAlerts.filter((chip) => chip.key !== chipToDelete.key);
localStorage.setItem('notys', JSON.stringify(local)); };
其中一个问题可能是您没有断开与套接字的连接,因此第一次订阅在closure中具有chipData的初始值时会将其带回来。取消订阅effect的清理服务可能会有所帮助,类似于:
useEffect(() => {
/* your code */
> stompClient.connect({}, function (frame) {
> subscription = stompClient.subscribe('/ws/alertNotification', function (greeting) {
> if (stompClient !== null) {
> stompClient.disconnect();
> }
>
> setChipData([
> ...chipData,
> {
> key: greeting.headers['message-id'],
> label: JSON.parse(greeting.body).content,
> },
> ]);
> });
> });
return () => subscription && subscription.unsubscribe();
}, [chipData]);
此外,出于性能考虑,我们可以在每次更新chipData时跳过重新创建连接/订阅。我们可以使用setChipData参数的回调版本,它引用状态的最新值
setChipData(prevData => [
> ...prevData,
> {
> key: greeting.headers['message-id'],
> label: JSON.parse(greeting.body).content,
> },
> ]);
因此,我们可以将[chipData]替换为[],作为useEffect的第二个参数,并在每个组件加载时仅打开一次连接