I'm trying to connect to a websocket server in react but I have to get the connection config from an api. I can't find the right pattern to do that.
I need to:
- Get the config from the api using react-query
- Create a client when the config is available
- Save the client in a state
- Update the client when the config changes
- Disconnect from the client on unmount
I'm using MQTT.js here because I want to connect to a mqtt broker, but it's the same thing as websockets. I just want to find the right pattern
Here is some of my attempts:
import mqtt from "mqtt"
export function useMqttClient() {
const [client, setClient] = useState();
const { data: config } = useQuery(/* ... */);
useEffect(() => {
if(config && !client) {
setClient(mqtt.connect(config))
}
}, [config, client])
// ...
}
The problem with this approach is that it doesn't end the connection (client.end()) when the component that uses useMqttClient unmounts. As the result, it tries to reconnect with the same config when the user navigates back to the same page and that's a problem for us. Also it doesn't update the client when config changes.
import mqtt from "mqtt"
export function useMqttClient() {
const [client, setClient] = useState();
const { data: config } = useQuery(/* ... */);
useEffect(() => {
if(config && !client?.connected) {
setClient(mqtt.connect(config))
}
return () => client?.end()
}, [config, client])
// ...
}
This time I end the connection in the cleanup function but I end up in an infinite loop. client is an instance of a class and config is an object so both of them could cause the infinite loop. But I don't know how to stop it.