Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kamiloox/use-socket-io-react
React.js wrapper for socket.io-client
https://github.com/kamiloox/use-socket-io-react
reactjs socket-io typescript websocket
Last synced: 3 months ago
JSON representation
React.js wrapper for socket.io-client
- Host: GitHub
- URL: https://github.com/kamiloox/use-socket-io-react
- Owner: kamiloox
- License: mit
- Created: 2022-09-02T20:57:51.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2023-10-12T13:08:55.000Z (about 1 year ago)
- Last Synced: 2024-10-10T12:59:48.000Z (3 months ago)
- Topics: reactjs, socket-io, typescript, websocket
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/use-socket-io-react
- Size: 143 KB
- Stars: 4
- Watchers: 1
- Forks: 1
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Written with ❤️ It's 100% typesafe to make React.js developer experience better with socket.io-client.
## Key features
- Module augmentation to reuse your types that are on a backend. More on that [here](#module-augmentation)
- TypeScript support
- Reusable React.js hooks## Installation
- With yarn
```sh
yarn add use-socket-io-react
```- With npm
```sh
npm install use-socket-io-react
```## Setup
Wrap the application with a `SocketProvider`. For example, with React 18 it can be done like so:
```ts
const SERVER_URI = 'http://localhost:4000';ReactDOM.render(
,
document.getElementById('root'),
);
```The URI prop needs to point to a backend server. Don't forget about handling a [CORS policy](https://socket.io/docs/v4/handling-cors/#configuration) on a server because since version 3 of a `socket.io` it needs to be set explicitly.
## Handling events
There is a hook called `useSocketEvent`. As a first argument, it takes an event name and in a resolution, it returns an object with a `data` array. Values in an array match to an order in which values are passed to an `io.emit` on a server.
```ts
// Server
io.emit('alert', 'Hey, you are the best!');
``````ts
// Client
const {
data: [alert],
} = useSocketEvent<[string]>('alert');if (alert) {
returnYou received an alert: ${alert}
;
}
```Alternatively `useSocketEvent` provides a handler callback that gets dispatched when the socket receives an event.
```ts
// Server
io.emit('chat', 'Hello John!', '12:38');
``````ts
// Client
const [messages, setMessages] = useState<
Array<{ message: string; sentAt: string }>
>([]);const handleMessage = ([message, sentAt]: [string, string]) => {
setMessages([...messages, { message: message, sentAt: sentAt }]);
};useSocketEvent<[string, string]>('chat', {
handler: handleMessage,
});return (
{messages.map(({ message, sentAt }) => (
{message} ({sentAt})
))}
);
```## Emitting events
For emitting there is a hook called `useSocketEmit`. It doesn't take any argument but it returns an `emit` function.
```ts
const { emit } = useSocketEmit();emit<[string]>('message', ['Hey, this is my message']);
```You can provide a generic of how your emitted values need to look, but that's not recommended. Take a look at [module augmentation](#module-augmentation)
## Socket state
Hook called `useSocket` stores values about a current socket state. It knows e.g. if a socket is either connected or there is some error.
```ts
const {
socket,
status,
isConnected,
isConnecting,
isDisconnected,
disconnectReason,
isError,
error,
} = useSocket();// Or you can check: status === 'error'
if (isError) {
returnError! {error}
;
}if (isDisconnected) {
returnSocket disconnected {disconnectReason}
;
}if (isConnecting) {
returnIs loading
;
}
```In addition, `useSocket` returns a native socket from a `socket.io-client` if some feature is needed that's currently beyond this library.
Module augmentation
Socket.io introduces [TypeScript support](https://socket.io/docs/v4/typescript/). This library supports this idea too. It's possible to abandon passing generic to every `useSocketEvent` and `useSocketEmit` hook thankfully to a module [augmentation feature](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation).
In the a root of a project (e.g. in the `src`) create a file called `types/use-socket-io-react.d.ts` and paste this.
```ts
import 'use-socket-io-react';declare module 'use-socket-io-react' {
interface ServerToClientEvents {
chat: (message: string, sentAt: number) => void;
}interface ClientToServerEvents {
alert: (content: string) => void;
}
}
```These interfaces are copied directly from a backend. There is no need to worry about the specific conventions for this package. If on a backend server a TypeScript is used then it's easy to extend it.
```ts
const { emit } = useSocketEmit();// Argument of type '[]' is not assignable to parameter of type '[content: string]'.
// Source has 0 element(s) but target requires 1.
emit('alert', []);
``````ts
const handleMessage: EventHandler<'chat'> = ([message]) => {
console.log(`There is a message ${message}`);
};useSocketEvent('chat', {
handler: handleMessage,
});
```> Disclaimer. If this feature doesn't work try adding a path to a `typeRoots` in a `tsconfig.json`.
```ts
{
"compilerOptions": {
"typeRoots": ["./src/types"]
},
}
```### Additional notes
- Package uses the 4th major version of a `socket.io-client`.
- This project uses [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) convention
- This is still in development. But there are more incoming updates in the future!