robtaussig / react-use-websocket

React Hook for WebSocket communication
MIT License
1.63k stars 135 forks source link

How to click the button to connect? #153

Closed suttapak closed 1 year ago

suttapak commented 2 years ago

Hello, I have a problem with my project. The problem is when i open the page is store useWebSocket hook it connects to my ws server but i have to click it before connecting. not connected when opening that page. thank you for answer šŸ˜.

robtaussig commented 2 years ago

@suttapak could you please provide an example of how you are using it? Iā€™m not clear on whether you want a solution to defer opening the websocket until after clicking on a button, or whether you are finding that this is the only time it works for you

youngchingjui commented 1 year ago

I have a similar situation as @suttapak:

In my app, the user will record their voice and send the transcription directly to AssemblyAI for live transcription. The user will push a button to record, and push 2nd button to stop recording.

During the recording, we need to open up the websocket to AssemblyAI to stream the audio recordings and receive back transcriptions.

We can't turn on the websocket immediately when the page loads, because the user may not have opened the mic, mic permissions may have not been granted yet, the user may not be ready to speak, etc.

If we turn on websocket too early with AssemblyAI (AAI), AAI will time out the websocket after 60 seconds if no data is sent.

I understand Websocket API does not include a start() or connect() method.

I'm considering making a separate React Component that will instantiate the useWebSocket hook, and rendering that component when clicking the button. Perhaps this should be the answer, given WebSocket API doesn't have a method to handle this.

robtaussig commented 1 year ago

Hi @youngchingjui and @suttapak ,

There are two problems here to solve. One is opening a websocket only after a user has clicked a button (or some other condition is fulfilled). The best way to do this is to store a flag in React.useState:

const [connect, setConnect] = React.useState(false);
const { lastMessage, sendMessage } = useWebSocket('some-url', {}, connect);

//JSX
<button onClick={() => setConnect(prev => !prev)}>Click Me to toggle connection</button>

The other question is how to prevent the connection from closing when changing pages. This depends on your application architecture, but ultimately you should instantiate the WebSocket at the root of your application (before you render you Router from react-router. If you do it like this:

const App = () => {
  useWebSocket('url', { share: true });
  return (
    <Router>
      //Your routes
    </Router>
  );
};

The WebSocket connect will remain live across route changes. In your components, you can call the websocket hook (using the share option), without it opening a new websocket.