Use React Context for sharing socket

This commit is contained in:
Kalle 2022-03-29 23:40:08 +03:00
parent 7d4c4a73f4
commit 8d647eaeff
3 changed files with 39 additions and 6 deletions

View File

@ -1,15 +1,16 @@
import io from "socket.io-client";
import * as React from "react";
import { useSocket } from "~/utils/socketContext";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function useSocketEvent(event: string, handler: (data: any) => void) {
React.useEffect(() => {
const socket = io();
const socket = useSocket();
React.useEffect(() => {
if (!socket) return;
socket.on(event, handler);
return () => {
socket.close();
socket.off(event);
};
}, [handler]);
}, [socket, handler]);
}

View File

@ -17,6 +17,8 @@ import resetStyles from "~/styles/reset.css";
import globalStyles from "~/styles/global.css";
import layoutStyles from "~/styles/layout.css";
import { DISCORD_URL } from "./constants";
import { io, Socket } from "socket.io-client";
import { SocketProvider } from "./utils/socketContext";
export const links: LinksFunction = () => {
return [
@ -52,12 +54,24 @@ export const loader: LoaderFunction = ({ context }) => {
export const unstable_shouldReload = () => false;
export default function App() {
const [socket, setSocket] = React.useState<Socket>();
const children = React.useMemo(() => <Outlet />, []);
const data = useLoaderData<RootLoaderData>();
React.useEffect(() => {
const socket = io();
setSocket(socket);
return () => {
socket.close();
};
}, []);
return (
<Document ENV={data.ENV}>
<Layout>{children}</Layout>
<SocketProvider socket={socket}>
<Layout>{children}</Layout>
</SocketProvider>
</Document>
);
}

View File

@ -0,0 +1,18 @@
import type { ReactNode } from "react";
import { createContext, useContext } from "react";
import type { Socket } from "socket.io-client";
type ProviderProps = {
socket: Socket | undefined;
children: ReactNode;
};
const context = createContext<Socket | undefined>(undefined);
export function useSocket() {
return useContext(context);
}
export function SocketProvider({ socket, children }: ProviderProps) {
return <context.Provider value={socket}>{children}</context.Provider>;
}