Skip to content

Instantly share code, notes, and snippets.

@willybeans
Created February 10, 2024 15:14
Show Gist options
  • Save willybeans/7b807427a8480be7629cc9b8133e6f75 to your computer and use it in GitHub Desktop.
Save willybeans/7b807427a8480be7629cc9b8133e6f75 to your computer and use it in GitHub Desktop.
Websocket connection using context provider in React Native Expo using typescript
// a lot of context removed for brevity
import {
DarkTheme,
DefaultTheme,
ThemeProvider,
} from "@react-navigation/native";
import { SplashScreen, Stack } from "expo-router";
import { WebSocketProvider } from "../context/WebSocket";
function RootLayoutNav() {
const colorScheme = useColorScheme();
return (
<ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
<WebSocketProvider>
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
</Stack>
</WebSocketProvider>
</ThemeProvider>
);
}
import { createContext } from "react";
import { Websocket } from "./types";
const Context = createContext<Websocket>({} as Websocket);
export default Context;
import { Platform, StyleSheet } from "react-native";
import { useEffect } from "react";
import { useWebSocketContext } from "../../context/WebSocket";
import { Text, View } from "../../components/Themed";
export default function ExampleScreen() {
const { isReady, val, send } = useWebSocketContext();
useEffect(() => {
if (isReady) {
send("test message");
}
}, [isReady, send]);
return (
<View style={styles.container}>
<Text>
Ready: {JSON.stringify(isReady)}, Value: {val}
</Text>
</View>
);
}
import { WebSocketProvider } from "./Provider";
import useWebSocketContext from "./useWebSocketContext";
export { WebSocketProvider, useWebSocketContext };
import React, { useState, useEffect, useRef } from "react";
import Context from "./Context";
import { Websocket } from "./types";
export const WebSocketProvider: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const [isReady, setIsReady] = useState(false);
const [val, setVal] = useState(null);
const wsRef = useRef<WebSocket | null>(null);
useEffect(() => {
const ws = new WebSocket("wss://echo.websocket.events/");
ws.onopen = () => {
setIsReady(true);
};
ws.onclose = () => {
setIsReady(false);
};
ws.onmessage = (event) => setVal(event.data);
wsRef.current = ws;
return () => {
ws.close();
};
}, []);
const ret = {
isReady,
val,
send: wsRef.current?.send.bind(wsRef.current),
} as Websocket;
return <Context.Provider value={ret}>{children}</Context.Provider>;
};
export interface Websocket {
isReady: boolean;
val: any | null;
send: WebSocketSend;
}
export type WebSocketSend = (
data: string | ArrayBufferLike | Blob | ArrayBufferView
) => void;
export interface MessageBody { // you can customize this however you want!
time: string;
name: string;
content: string;
}
export type WebSocketContext = [
isReady: boolean,
receivedMessages: MessageBody[],
send: WebSocketSend | undefined
];
import { useContext, useEffect } from "react";
import Context from "./Context";
const useWebSocketContext = () => {
const webSocketContext = useContext(Context);
return webSocketContext;
};
export default useWebSocketContext;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment