React Native JavaScript: TypeError: null is not an object (evaluating 'chatSocket.send')

React Native JavaScript: TypeError: null is not an object (evaluating 'chatSocket.send')

所以我有一个 React Native Project and I am using JavaScript WebSockets。当我尝试将有效负载发送到 websocket 时,出现此错误:

TypeError: null is not an object (evaluating 'chatSocket.send')

(chatSocket是我的webSocket)

import React, {useEffect, useState} from 'react';
import {
  Button,
  FlatList,
  StyleSheet,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from 'react-native';

const Chat = ({route, navigation}) => {
  const { username, chatid } = route.params;


  useEffect(() => {
    setupWebSocket(chatid)
  }, [])



  var chatSocket = null;
  var roomId = null;
  
  function closeWebSocket(){
      if(chatSocket != null){
          chatSocket.close()
          chatSocket = null
      }
  }
  
  function setupWebSocket(room_id){
  
      console.log("setupWebSocket: " + room_id)
  
      roomId = room_id
  
      // close previous socket if one is open
      closeWebSocket()
  
  
      var ws_path = "ws://192.168.2.110:8000/chat/" + room_id + "/" + "?ec5ccab5d15ad8d6fd5e3f91cbfd8b6dac8fcf69";
  
      
      
      // console.log("Connecting to " + ws_path);
      chatSocket = new WebSocket(ws_path);
  
      // Handle incoming messages
      chatSocket.onmessage = function(message) {
          // Decode the JSON
          // console.log("Got chat websocket message " + message.data);
          console.log("Got websocket message.");
          var data = JSON.parse(message.data);
          // console.log(data)
  
          // display the progress bar?
          // displayChatroomLoadingSpinner(data.display_progress_bar)
  
          // Handle errors (ClientError)
          if (data.error) {
              console.error(data.error + ": " + data.message)
              return;
          }
          // Handle joining (Client perspective)
          if (data.join) {
              console.log("Joining room " + data.join);
          }
          // Handle leaving (client perspective)
          if (data.leave) {
              // do nothing
              console.log("Leaving room " + data.leave);
          }
          if (data.msg_type == 0) {
            appendChatMessage(data, true)
          }
      };
  
      chatSocket.addEventListener("open", function(e){
          console.log("ChatSocket OPEN")
          // join chat room get data from local database here
          if(1 == 1){
              chatSocket.send(JSON.stringify({
                  "command": "join",
                  "room": roomId,
              }));
          }
      })
  
      chatSocket.onclose = function(e) {
          console.log('Chat socket closed.');
      };
  
      chatSocket.onOpen = function(e){
          console.log("ChatSocket onOpen", e)
      }
  
      chatSocket.onerror = function(e){
          console.log('ChatSocket error', e)
      }
  
      if (chatSocket.readyState == WebSocket.OPEN) {
          console.log("ChatSocket OPEN")
      } else if (chatSocket.readyState == WebSocket.CONNECTING){
          console.log("ChatSocket connecting..")
      }
  }
 
  const appendChatMessage = (data, isNewMessage) => {

    var msg = data.message
    var timestamp = data.natural_timestamp
    var user_id = data.user_id
    var username = data.username


    logData(msg, timestamp, user_id, username, isNewMessage)
  }

  const [newChatMessage, setNewChatMessage] = useState({})
  // console.log(newChatMessage)

  const logData = (msg, timestamp, user_id, username, isNewMessage) => {
    if(isNewMessage){
      // console.log(msg)
      // console.log(username)
    }
    setNewChatMessage({...newChatMessage, 
      "message": msg,
      "username": username
    })
  };



  const [message, setMessage] = useState("")


  const handleSend = (messagex) => {
    chatSocket.send(JSON.stringify({
      "command": "send",
      "message": messagex,
      "room": "1"
    }));
  };

  return (
    <View>
      <Text style={{textAlign: "center", fontSize: 30}}>Chat</Text>
        <TextInput placeholder="Message" onChangeText={(value) => setMessage(value)} style={{borderRadius: 10, borderColor: "black", borderWidth: 2}}/>
        <Button title="Send" onPress={() => handleSend(message)} />
    </View>
  );
};

export default Chat;

我认为 React 钩子

有错误

我会尽快解释代码:

该组件是从导航中调用的 App.Js。没有错误,一切正常。比我在前端设置 WebSocket。它使用域中的 Auth-Token 连接到 Ip(这不是最佳的,仅用于测试)。如果用户在 <TextInput /> 中输入内容,则 useState() 将被更新,如果我点击按钮 send,则应发送数据。

现在奇怪的部分来了:有时它可以工作,但如果我再次单击按钮并延迟 1-60 秒,它就不会工作。 :/

如果您需要更多信息,请编写命令。也许你有错误:)

问题是您的 chatSocket 在函数组件的主体中被定义为普通变量。每次函数组件 run/rendered 时,都会重新创建在函数组件上定义的任何内容,因为它只是一个函数。

我建议将套接字包裹在 useRef 中以在渲染之间保留它。

类似于const chatSocket = useRef(null);

然后在您的设置函数中,用 chatSocket.current = new WebSocket(ws_path);

初始化它