Skip to content

Instantly share code, notes, and snippets.

@Mulperi
Last active January 13, 2022 08:22
Show Gist options
  • Save Mulperi/9cd8a7b877a391f6ffc6abd73517e5a5 to your computer and use it in GitHub Desktop.
Save Mulperi/9cd8a7b877a391f6ffc6abd73517e5a5 to your computer and use it in GitHub Desktop.
React redux-saga with websocket
import { put, take, takeEvery, call, select } from "redux-saga/effects";
import { eventChannel } from "redux-saga";
import { io, Socket } from "socket.io-client";
/* Event channel for converting incoming socket messages to saga events. */
function createEventChannel(mySocket: Socket<any>) {
return eventChannel((emit) => {
mySocket.onAny((type: string, payload: any) => emit({ type, payload }));
return () => {
mySocket.close();
};
});
}
const mySocket = io("ws://localhost:5000/todos");
/* Initialize the saga event channel for websocket events. */
function* socketInitEffect(): Generator<any, any, any> {
const channel = yield call(createEventChannel, mySocket);
while (true) {
const message = yield take(channel);
console.log("Received websocket message", message);
/* Based on websocket message type, dispatch redux actions accordingly. */
switch (message.type) {
case "initial_data":
yield put(todosSet({ todos: message.payload }));
break;
default:
break;
}
}
}
function todosToggleEffect(action: any) {
mySocket.emit("toggle", action.payload.id);
}
function socketCloseEffect(action: any) {
mySocket.close();
}
function* watchTodosActions() {
yield takeEvery(socketInit, socketInitEffect);
yield takeEvery(socketClose, socketCloseEffect);
yield takeEvery(todosToggle, todosToggleEffect);
}
export default watchTodosActions;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment