Reputation: 928
So I have an React Native Project and I am using JavaScript WebSockets. When I try to send a payload to the websocket I get this error:
TypeError: null is not an object (evaluating 'chatSocket.send')
(The chatSocket is my 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;
I think there is an error with React Hooks 🤔
I will shortly explain the code:
The component is called from a Navigation App.Js. There is no error everything works fine. Than I setup the WebSocket on the frontend. It connects to an Ip with the Auth-Token in the domain (This isn't optimal, just for testing). Than if the user puts something in the <TextInput />
a useState()
will be updated and if I than click on the button send
the data should be sent.
So now comes the weird part: Sometimes it works and if I click on the button again with a delay of 1-60 seconds it won't work. :/
If you need more information please write a command. Maybe you had the error :)
Upvotes: 0
Views: 1268
Reputation: 2599
The issue is that your chatSocket
is getting defined as a plain variable in the body of the function component. Anything defined on a function component will be recreated every time the component is run/rendered, as it's just a function.
I would recommend wrapping the socket in a useRef
to persist it between renders.
Something like const chatSocket = useRef(null);
and then in your setup function, initialize it with chatSocket.current = new WebSocket(ws_path);
Upvotes: 1