The problem i am facing is that when ever user is navigate to chat page after login socket is never created but whenever i initialized the socket in function scope it creates the socket connection when the user logged in but i am not using it because it because it creates socket connectins rapdily due to creation of new socket when the function is called
This is the login component in which when the user logged in i am navigating it to chat page
import React from 'react';
import axios from 'axios';
import { useForm } from 'react-hook-form';
import { useDispatch } from 'react-redux';
import { login } from '../ReduxToolkit/authSlice';
import { useNavigate } from 'react-router-dom';
import Allid from './Allid';
function Login() {
const { register, handleSubmit } = useForm();
const [showPopup, setShowPopup] = useState(false)
const navigate=useNavigate()
const dispatch=useDispatch()
const onlogin = async (data) => {
try {
const response = await axios.post('http://localhost:8000/api/v1/users/login', data, { withCredentials: true });
if (!response) {
console.log("Response not found; something went wrong in the login request");
}
dispatch(login(response.data.data))
console.log(response);
navigate('/chat')
setShowPopup(true)
setTimeout(() => setShowPopup(false), 1000);
} catch (error) {
console.log("Something went wrong", error);
}
};
return (
<div className="flex items-center justify-center min-h-screen bg-gray-100" style={{ backgroundImage: 'url(".jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load")', backgroundSize: 'cover' }} aria-label="Vivid blue colonial wall in Arequipa, Peru">
<meta name="description" content="Log in to your account to access and manage your blog posts and profile."/>
<meta name="keywords" content="login, sign in, blog access"/>
<meta name="author" content="Your Blog Name"/>
<title>Login - Your Blog</title>
<form onSubmit={handleSubmit(onlogin)} className="bg-white p-6 rounded shadow-md w-full max-w-sm bg-opacity-80">
<div className="mb-4">
<label className="block text-gray-700 text-sm font-bold mb-2">Email</label>
<input
type="email"
placeholder="Enter the email"
{...register('email', { required: true })}
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
/>
</div>
<div className="mb-6">
<label className="block text-gray-700 text-sm font-bold mb-2">Password</label>
<input
type="password"
placeholder="Enter the password"
{...register('password', { required: true })}
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline"
/>
</div>
<div className="flex items-center justify-between">
<button type="submit" className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
Login
</button>
</div>
</form>
{showPopup && (
<div className="fixed top-0 left-0 right-0 p-4 bg-green-500 text-white text-center">
Logged in successfully!
</div>
)}
</div>
);
}
export default Login;
This is the chat component in which i am taking instance of socket from another compnent:
import {useForm} from 'react-hook-form'
import {useSelector} from 'react-redux'
import initializesocket from './Socket'
import useSocketVisibility from './VisibilityHook'
function Chat() {
const{handleSubmit,register,reset}=useForm()
const userData=useSelector((state)=>state.userData?._id)
console.log(userData)
const [messages, setmessages] = useState([])
let socket
useEffect(()=>{
if(userData)
{
socket=initializesocket(userData)
socket.on('message', (latestmsg) => {
console.log(latestmsg)
setmessages((prev) => [...prev, latestmsg])
})
return () => {
socket.off('connect');
socket.off('message');
socket.off('disconnect')
socket.close();
}}
},[userData])
const sendmsg = (data) => {
if(socket&&socket.connected){
console.log(data)
socket.emit('sendmessage',data.message)
reset()
}else{
console.log("not connected")
}
}
return (
<>
{/* <form onSubmit={handleSubmit(sendmsg)}>
<div>
{messages.map((eachmsg,index)=>(
<p key={index}>{eachmsg}:{index}</p>
))}
</div>
<div>
<input type="text"
className='border-2 border-black'
{...register('message',{required:true})}
/>
<button type='submit'>Submit</button>
</div>
</form> */}
<div>very good chating</div>
</>
)
}
export default Chat
This is the socket from which i am taking instance:
let socket = null; // Declare globally
const initializesocket = (userData) => {
if (!socket) {
socket = io('http://localhost:8000', {
transports: ['websocket'],
});
// Add event listeners only once
socket.on('connect', () => {
console.log("Socket connected", socket.id);
console.log(socket.connected);
if (userData) {
socket.emit('logindata', userData);
}
});
socket.on('disconnect', () => {
console.log('Socket disconnected');
});
} else if (socket && userData) {
// Emit userData if socket is already initialized
socket.emit('logindata', userData);
}
return socket;
};
export default initializesocket;
I want to establish a real time chat application but i am facing a problem that socket instance is not created