useEmitter
Introduction
This hook send events to the server. The minimum requirement for useEmitter
is a prepared
Emitter
.
If you intend to listen
to events from the server, we recommend choosing the
useListener
hook.
Initialization
const { emit, timestamp, connected, onEvent, onError, onReconnecting } = useEmitter(postLogin);
How it works?
useEmitter
executes a Emitter when a emit()
function returned from it gets triggered. It uses dependency
tracking to limit re-rendering and improve performance. Under the hood, communication with the core systems is
established by event emitters. Many "helper hooks"
(such as onEvent
, onError
, onReconnecting
, etc.) are
returned; these will help handle the request flow and lifecycle. This approach avoids overloading the base hook with
callback logic. It also helps improve code readability, decreases code complication, and promotes more organized code.
import { socketInstance } from "./socket";
export const emitMessage = socketInstance.createEmitter<ChatMessageType, AcknowledgementResponseType>()({
endpoint: "chat-message", // endpoint of the event
});
Use it in your component.
import { useEmitter } from "@hyper-fetch/react";
import { emitMessage } from "./api";
const MessageComponent: React.FC = () => {
const { emit, timestamp, connected, onEvent, onError, onReconnecting } = useEmitter(postLogin);
onEvent((emitter) => {
// Event before we send event message
console.log(emitter); // Emitter instance
});
onError((error) => {
console.log(error); // Error Event
});
onReconnecting((reconnectingAttempt) => {
console.log(reconnectingAttempt); // 1
});
const onSubmit = (values: Values) => {
// ResponseDataType is automatically inherited from Emitter class
const acknowledge = (error: Error, data: ResponseDataType) => {
if (error) {
alert("No server response!");
} else {
alert("Message received on server.");
}
};
emit({ data: values }, acknowledge);
};
return (
<Formik onSubmit={onSubmit} validationSchema={validationSchema}>
<Form>
<FormInput name="message" label="Message" placeholder="Write message" />
<Button type="submit" variant="contained" disabled={submitting} className={styles.submit}>
Send
</Button>
</Form>
</Formik>
);
};
Passing data and params
Data and parameters can be passed in several ways. One option is to use setData
method on the
Emitter
.
const { emit } = useEmitter(emitMessage.setData({ message: "New message" }));
However, you may need to pass parameters dynamically, which requires using emit
function options.
const { emit } = useEmitter(emitMessage);
const handleSubmit = (id: number, name: string) => {
// ResponseDataType is automatically inherited from Emitter class
emit({ data: { name } }, (error: Error, data: ResponseDataType) => {
if (error) {
alert("No server response!");
} else {
alert("Message received on server.");
}
});
};
Options
These configuration options should be provided as a second parameter:
const { ... } = useEmitter(emitter, options)
{
dependencyTracking: boolean;
}
Returns
Returned values from this hook:
const values = useEmitter(emitter);
{
connected: boolean;
connecting: boolean;
emit: ExtractEmitterHasDataType<Emitter> extends false ? (options: [object Object]) => string : (ExtractRouteParams<ExtractEmitterEndpointType<Emitter>> extends NegativeTypes ? (options?: [object Object]) => string : (ExtractEmitterHasParamsType<Emitter> extends false ? (options: [object Object]) => string : (options?: [object Object]) => string));
onClose: (callback: VoidFunction) => void;
onConnecting: (callback: VoidFunction) => void;
onError: (callback: (event: ErrorType) => void) => void;
onEvent: (callback: (emitter: EmitterType) => void) => void;
onOpen: (callback: VoidFunction) => void;
onReconnecting: (callback: (attempts: number) => void) => void;
onReconnectingStop: (callback: (attempts: number) => void) => void;
reconnect: number;
setConnected: (connected: boolean) => void;
setConnecting: (connecting: boolean) => void;
setData: (data: unknown) => void;
setTimestamp: (timestamp: number) => void;
timestamp: number;
}