Ich muss eine Verbindung zum WebSockets-Server herstellen und seine Nachrichten protokollieren. Mit der React-Klassenkomponente würde ich diese Logik einfügen componentDidMount
Lebenszyklus-Hook und glücklich weitermachen, aber ich bin mir nicht sicher, wie ich es mit Hooks richtig implementieren soll.
Hier mein erster Versuch.
import React, {useEffect} from 'react';
export default function AppWs() {
useEffect(() => {
let ws = new WebSocket('wss://ws.kraken.com/');
ws.onopen = () => console.log('ws opened');
ws.onclose = () => console.log('ws closed');
ws.onmessage = e => {
const message = JSON.parse(e.data);
console.log('e', message);
};
return () => {
ws.close();
}
}, []);
return (
<div>hooks + ws</div>
)
}
Ich habe Verbindungs- und Protokolllogik hinzugefügt useEffect
, stellte ein leeres Array mit Abhängigkeiten bereit, und alles funktionierte großartig. Bis ich hinzufügen musste pause
Zustand, um die Protokollierung anzuhalten.
export default function AppWs() {
const [isPaused, setPause] = useState(false);
useEffect(() => {
let ws = new WebSocket('wss://ws.kraken.com/');
ws.onopen = () => console.log('ws opened');
ws.onclose = () => console.log('ws closed');
ws.onmessage = e => {
if (isPaused) return;
const message = JSON.parse(e.data);
console.log('e', message);
};
return () => {
ws.close();
}
}, []);
return (
<div>
<button onClick={() => setPause(!isPaused)}>{isPaused ? 'Resume' : 'Pause'}</button>
</div>
)
}
ESLint fing an, mich anzuschreien, dass ich hinzufügen sollte isPaused
Zustand als Abhängigkeit von useEffect
.
Na gut, fertig.
Aber ich habe eine erneute Verbindung zum WS-Server bemerkt, nachdem ich jedes Mal auf die Schaltfläche geklickt habe. Das ist eindeutig nicht das, was ich will.
Meine nächste Iteration war, zwei zu verwenden useEffect
s: eine für die Verbindung und eine für die Nachrichtenverarbeitung.
export default function AppWs() {
const [isPaused, setPause] = useState(false);
const [ws, setWs] = useState(null);
useEffect(() => {
const wsClient = new WebSocket('wss://ws.kraken.com/');
wsClient.onopen = () => {
console.log('ws opened');
setWs(wsClient);
};
wsClient.onclose = () => console.log('ws closed');
return () => {
wsClient.close();
}
}, []);
useEffect(() => {
if (!ws) return;
ws.onmessage = e => {
if (isPaused) return;
const message = JSON.parse(e.data);
console.log('e', message);
};
}, [isPaused, ws]);
return (
<div>
<button onClick={() => setPause(!isPaused)}>{isPaused ? 'Resume' : 'Pause'}</button>
</div>
)
}
Dies funktioniert wie erwartet, aber ich habe das Gefühl, dass ich etwas verpasse und diese Aufgabe einfacher gelöst werden kann, mit einem useEffect
. Bitte helfen Sie, den Code umzugestalten, und überzeugen Sie mich, dass ich React-Hooks auf die richtige Weise verwende. Vielen Dank!