React App crashes without invoking WebSocket.close() function in useEffect cleanup function

I’m building a test app that connects to a server via WebSocket. The app crashes when I don’t use the WebSocket.close() function in the cleanup part of the useEffect hook. The app works fine when WebSocket.close() is included, ofc I know I should close connection/clean after using it but error references the some kind of ?object? (Error is listed below). Why does this happen?

I’ve tried to understand the issue, and I wonder if it’s related to something that happens in the background. From what I know, cleanup happens after the render, so it shouldn’t directly impact the rendering or state before the component renders. Is my understanding correct, or am I missing something?

Uncaught runtime errors: ERROR An attempt was made to use an object that is not, or is no longer, usable ./src/CommunicationComponent.jsx/WebSocketComponent/
</socketRef.current.onopen@http://localhost:3000/static/js/bundle.js:191:27 EventHandlerNonNull*./src/CommunicationComponent.jsx/WebSocketComponent/<@http://localhost:3000/static/js/bundle.js:189:7 commitHookEffectListMount@http://localhost:3000/static/js/bundle.js:26115:30
  commitPassiveMountOnFiber@http://localhost:3000/static/js/bundle.js:27608:42 commitPassiveMountEffects_complete@http://localhost:3000/static/js/bundle.js:27580:38 commitPassiveMountEffects_begin@http://localhost:3000/static/js/bundle.js:27570:45 commitPassiveMountEffects@http://localhost:3000/static/js/bundle.js:27560:38
  flushPassiveEffectsImpl@http://localhost:3000/static/js/bundle.js:29443:32 flushPassiveEffects@http://localhost:3000/static/js/bundle.js:29396:18 ./node_modules/react-dom/cjs/react-dom.development.js/commitRootImpl/<@http://localhost:3000/static/js/bundle.js:29211:13
  workLoop@http://localhost:3000/static/js/bundle.js:36363:46 flushWork@http://localhost:3000/static/js/bundle.js:36341:18 performWorkUntilDeadline@http://localhost:3000/static/js/bundle.js:36578:25 EventHandlerNonNull*./node_modules/scheduler/cjs/scheduler.development.js/<@http://localhost:3000/static/js/bundle.js:36614:7
  ./node_modules/scheduler/cjs/scheduler.development.js@http://localhost:3000/static/js/bundle.js:36664:5 options.factory@http://localhost:3000/static/js/bundle.js:41901:31 __webpack_require__@http://localhost:3000/static/js/bundle.js:41331:32 fn@http://localhost:3000/static/js/bundle.js:41560:21
  ./node_modules/scheduler/index.js@http://localhost:3000/static/js/bundle.js:36679:20 options.factory@http://localhost:3000/static/js/bundle.js:41901:31 __webpack_require__@http://localhost:3000/static/js/bundle.js:41331:32 fn@http://localhost:3000/static/js/bundle.js:41560:21
  ./node_modules/react-dom/cjs/react-dom.development.js/<@http://localhost:3000/static/js/bundle.js:6083:40 ./node_modules/react-dom/cjs/react-dom.development.js@http://localhost:3000/static/js/bundle.js:31842:5 options.factory@http://localhost:3000/static/js/bundle.js:41901:31
  __webpack_require__@http://localhost:3000/static/js/bundle.js:41331:32 fn@http://localhost:3000/static/js/bundle.js:41560:21 ./node_modules/react-dom/index.js@http://localhost:3000/static/js/bundle.js:31913:20 options.factory@http://localhost:3000/static/js/bundle.js:41901:31
  __webpack_require__@http://localhost:3000/static/js/bundle.js:41331:32 fn@http://localhost:3000/static/js/bundle.js:41560:21 ./node_modules/react-dom/client.js@http://localhost:3000/static/js/bundle.js:31856:28 options.factory@http://localhost:3000/static/js/bundle.js:41901:31
  __webpack_require__@http://localhost:3000/static/js/bundle.js:41331:32 fn@http://localhost:3000/static/js/bundle.js:41560:21 ./src/index.js@http://localhost:3000/static/js/bundle.js:298:93 options.factory@http://localhost:3000/static/js/bundle.js:41901:31
  __webpack_require__@http://localhost:3000/static/js/bundle.js:41331:32 @http://localhost:3000/static/js/bundle.js:42544:56 @http://localhost:3000/static/js/bundle.js:42546:12

Working Client Code:

import React, { useEffect, useRef } from 'react';

export default function WebSocketComponent({ children }) {
  const socketRef = useRef(null);
  const isEstablish = useRef(false);  // Tracks if the WebSocket connection is established
  const inputRef = useRef(null);  // Ref for the input field

  useEffect(() => {
    if(!isEstablish.current)
    {
        socketRef.current = new WebSocket('ws://localhost:8080');

        socketRef.current.onopen = () => {
        console.log('WebSocket connection established.');
        socketRef.current.send('Hello Server!');
        isEstablish.current = true;  // Mark connection as established
        };

        socketRef.current.onmessage = (event) => {
        console.log('Message from server:', event.data);
        };

        socketRef.current.onerror = (error) => {
        console.error('WebSocket error:', error);
        };

        socketRef.current.onclose = () => {
        console.log('WebSocket connection closed.');
        isEstablish.current = false;  // Mark connection as closed
        };
    }
    // Cleanup function 
    return () => {
      if (socketRef.current) {
        socketRef.current.close(); //it must be here, return a error in other case
        isEstablish.current = false;
      }
    };
  }, []); 

  // Function to send data to the server
  const sendToServer = () => {

    if (isEstablish.current && socketRef.current.readyState === WebSocket.OPEN) {
      const message = inputRef.current.value;
      console.log('Sent to server:', message);
      socketRef.current.send(message);  // Send message only if connection is open
    } else {
      console.error('WebSocket is not open. Cannot send message.');
    }
  };

  return (
    <div>
      <h1>WebSocket Example</h1>
      <input ref={inputRef} />
      <button onClick={sendToServer}>Send</button>
    </div>
  );
}