【问题标题】:Socket notifications套接字通知
【发布时间】:2023-03-19 22:44:01
【问题描述】:

我有一个从 Spring Boot 后端接收通知的屏幕,我将它们显示在一个铃铛中。删除通知时,它会很好地删除它,但是当另一个新通知到达时,它会加载我已经删除的通知。

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));   };

【问题讨论】:

    标签: javascript reactjs stomp rsocket-js


    【解决方案1】:

    其中一个问题可能是您没有断开与套接字的连接,因此第一次订阅(在闭包中具有 chipData 的初始值)会将其恢复。取消订阅效果清理可能会有所帮助,类似于:

    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 参数的 callback 版本,它引用状态的最新值。

    setChipData(prevData => [
    >           ...prevData,
    >           {
    >             key: greeting.headers['message-id'],
    >             label: JSON.parse(greeting.body).content,
    >           },
    >         ]);
    

    所以我们可以将 [chipData] 替换为 [] 作为 useEffect 的第二个参数,并且每次加载组件时只打开一次连接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-17
      • 2021-07-02
      • 2018-05-19
      相关资源
      最近更新 更多