Skip to content

Latest commit

 

History

History
142 lines (108 loc) · 3.89 KB

README.md

File metadata and controls

142 lines (108 loc) · 3.89 KB

React hooks for socket.io 4.x

Examples:


Usage:

  1. Wrap your components with the provider
  import { IoProvider } from 'socket.io-react-hook';

  <IoProvider>
    <App />       
  </IoProvider>
  import { useSocket, useSocketEvent } from 'socket.io-react-hook';

  const { socket, error } = useSocket();  
  const { lastMessage, sendMessage } = useSocketEvent(socket, 'message');

  OR

  const { lastMessage, sendMessage } = useSocketEvent('message');

If the socket parameter is not passed to useSocketEvent, the options of useSocket can be passed in the second parameter of useSocketEvent. For example

  const { lastMessage, sendMessage } = useSocketEvent('message', { path: "/socket", extraHeaders: ... });

useSocket and useSocketEvent forwards all relevant parameters to socket.io constructor.
See the available options here

If the socket connection depends on state, use it like this:
The connection will be initiated once the socket is enabled.
The connection for a namespace is shared between your components, feel free to use the hooks in multiple components.

import { useCookie } from 'react-use';
import { useSocket } from 'socket.io-react-hook';

export const useAuthenticatedSocket = (namespace?: string) => {
  const [accessToken] = useCookie('jwt');
  return useSocket(namespace, {
    enabled: !!accessToken,
  });
};

The useSocket hook always returns a socket-like object, even before a succesful connection. You don't have to check whether it is undefined.

Example:

export const useAuthenticatedSocket = (namespace?: string) => {
  const [accessToken] = useCookie('jwt');
  return useSocket(namespace, {
    enabled: !!accessToken,
  });
};
const Index = () => {

  const { socket, connected, error } = useAuthenticatedSocket();
  const { lastMessage, sendMessage } = 
    useSocketEvent<string>(socket, 'eventName');

  return <div>{ lastMessage }</div>
}
const Index = () => {
  const [messages, setMessages] = useState([]);
  const { socket, connected, error } = useAuthenticatedSocket();
  const onMessage = (message) => setMessages((state) => [...state, message]);
  useSocketEvent<string>(socket, "eventName", { onMessage });
  ...
};

useSocketEvent parameters:

  • socket: SocketIo object
  • event: string
  • options:
    • onMessage: (message) => void
    • keepPrevious: (default false) if true, useSocketEvent will immediately return the last available value of lastMessage after being remounted

Emitting messages works as always:

  const { socket, connected, error } = useSocket();
  socket.emit('eventName', data);

Or by calling sendMessage

  //Client
  const { socket, lastMessage, sendMessage } = useSocketEvent<string>(socket, 'eventName');
  ...
  const response = await sendMessage<{ status: string }>("hi server");
  console.log(response.status) // "ok"

  //Server
  io.on("connection", (socket) => {
    socket.on("eventName", (message, callback) => {
      console.log(message) // "hi server"
      callback({
        status: "ok"
      });
    });
  });

Typescript usage:

interface ServerToClientEvents {
  noArg: () => void;
  basicEmit: (a: number, b: string, c: any) => void;
  withAck: (d: string, callback: (e: number) => void) => void;
}

interface ClientToServerEvents {
  hello: () => void;
}
const { socket } = useSocket<ServerToClientEvents, ClientToServerEvents>();

socket.on("withAck", (d, callback) => {});
socket.emit("hello");