向服务器发送React和WebSocket消息

xyhw6mcr  于 2022-11-11  发布在  React
关注(0)|答案(1)|浏览(252)

因此,我遇到了一个问题,一个组件显示从资源服务器拉取的列表。然后它使用Stompjs建立一个WebSocket并发送消息。当我加载客户端时,开发控制台显示了它尝试调用onConnected方法()两次的日志,而我的日志显示了从一个组件的单次加载发送的两条newUser消息。
当我尝试调用submitBid()方法时,它抛出一个类型错误,指出

“类型错误:无法在提交竞价时读取未定义(阅读'send')的属性(AuctionList.js:76:1)"

我不知道为什么它在第36行的函数中运行良好,而在第36行的函数中定义了它,但在第36行的函数中却没有定义它。我已经在这个问题上纠结了好几天了,希望有人能告诉我代码中的错误......下面是组件代码......

import React from 'react'
import Stomp from 'stompjs';
import SockJS from 'sockjs-client';
import {useState, useEffect } from 'react';

function AuctionList({user, authCredentials, token}) {

 const [auctionItems, setAuctionItems] = useState([]);

 const [userData, setUserData] = useState({
                                            email: user.email,
                                            name: user.name,
                                            message: ''
                                          });

  const [bid, setBid] = useState(0.00);

  let stompClient;
  let socket;

const connect = async () => {
      socket = new SockJS('http://localhost:8080/ws')
      stompClient = Stomp.over(socket)
      stompClient.connect({}, onConnected, onError)
}

const onConnected = async () => {

  stompClient.subscribe('/topic/bids', onMessageReceived)

  stompClient.send("/app/socket.newUser",
      {},
      JSON.stringify({
          sender: user.name,
          type: 'NEW_USER',
          time: Date.now()
      })
  )
}

const onError = async (err) => {
  console.log(err);

}

const handleChange = async (e) =>{ 
  setBid(e.target.value);
}

const submitBid =  async (item) => { 

  let newMessage = {
                type: "BID",
                newBid: {
                        itemId: item.id,
                        email: user.email,
                        bidPrice: bid,
                        bidTime: new Date().getTime()
                       },
                sender: userData.email,
                time: new Date().getTime()
      };

            try { 
              stompClient.send("/socket.send", {}, JSON.stringify(newMessage));
            } catch(err){ 
              console.log(err); }
}

const onMessageReceived = async (payload)=>{
  console.log("onMessageReceived")
  console.log(payload)
}

const getAuctionList = async () => {

    const url = "http://localhost:8080/auctionlist";

    const init = {
      method: "GET",
        headers: {
            'Content-type': 'application/json',
            'Authorization': `Bearer ${token}`, // notice the Bearer before your token
        },
    };

    fetch(url, init)
    .then(response => response.json())
    .then(response => {setAuctionItems(response)})
};

useEffect( () => {
  getAuctionList();
  connect();
}, []);

return (
    <ul>  
        {auctionItems.map( item =>  {
          return(                <div key={item.id} className = "auctionItemComponent">
                <h3>{item.name}</h3>
                <span>{item.desc}</span>
                <span>Current Bid: ${item.itemStartingPrice}</span>
                <span>Minimum Bid: {item.itemMinBid}</span>
                <span>Time left</span>

                <input type="number" id="bidInput_" name="bidInput" onChange={handleChange} ></input>
                <button type='submit' onClick={submitBid}>Submit bid</button>
              </div>)

        })}
    </ul> 
  )
}

export default AuctionList

我也意识到我有一堆没有等待的异步函数,我试着添加它们,但没有任何变化。

siotufzp

siotufzp1#

这里的问题不是stompjs的问题,而是作用域的问题。你在React组件中有stompClient,但是submitBid中的stompClient是不同的。你可以用不同的方法来做。
1.将stompjs放在全局舞台中,如下例所示:https://playcode.io/972045
1.您可以使用useRef让客户端位于React组件中,并让React跟踪任何修改。
我个人认为像“连接”这样的东西应该远离React组件。你应该在一个不同的文件中拥有连接配置,并将一个示例导入到JSX文件中。

相关问题