useEventEmitter
Notification of events between multiple components can sometimes be a pain, and EventEmitter makes this process even easier.
Reference: useEventEmitter
The source code
import { useRef, useEffect } from "react";
type Subscription<T> = (val: T) = > void;
export class EventEmitter<T> {
// Use Set to store subscription callbacks
private subscriptions = new Set<Subscription<T>>();
// Iterate over the callback function
emit = (val: T) = > {
for (const subscription of this.subscriptions) { subscription(val); }}; useSubscription =(callback: Subscription<T>) = > {
const callbackRef = useRef<Subscription<T>>();
callbackRef.current = callback;
useEffect(() = > {
/ / subscribe
function subscription(val: T) {
if(callbackRef.current) { callbackRef.current(val); }}this.subscriptions.add(subscription);
return () = > {
this.subscriptions.delete(subscription); }; } []); }; }export default function useEventEmitter<T = void> () {
const ref = useRef<EventEmitter<T>>();
if(! ref.current) { ref.current =new EventEmitter();
}
return ref.current;
}
Copy the code
use
import React, { useRef, FC } from "react";
import { useEventEmitter } from "ahooks";
import { EventEmitter } from "ahooks/lib/useEventEmitter";
const MessageBox: FC<{
focus$: EventEmitter<void>; } > =function (props) {
return (
<div style={{ paddingBottom: 24}} >
<p>You received a message</p>
<button
type="button"
onClick={()= > {
props.focus$.emit();
}}>
Reply
</button>
</div>
);
};
const InputBox: FC<{
focus$: EventEmitter<void>; } > =function (props) {
const inputRef = useRef<any> ();/ / =. = useSubscription and scription returned by instances of EventEmitter are not supported by normal hooks. This gives access to the callback collection of the instance store
props.focus$.useSubscription(() = > {
inputRef.current.focus();
});
return (
<input
ref={inputRef}
placeholder="Enter reply"
style={{ width: "100% ",padding: "4px}} "/ >
);
};
export default function () {
const focus$ = useEventEmitter();
return (
<>
<MessageBox focus$={focus$} />
<InputBox focus$={focus$} />
</>
);
}
Copy the code
Comparing eventemitter3.js shows that there are many more methods worth extending