import { IMessageEvent, MessageEvent } from '@nitrots/nitro-renderer'; import { useCallback, useLayoutEffect, useRef, useState } from 'react'; import { useMessageEvent } from './useMessageEvent'; /** * Subscribe to a server message event and expose the latest derived * value as React state. Mirror of useNitroEventState for the Nitro * communication channel (request/response composers, push parsers). * * const data = useMessageEventState(SomeParser, e => e.getParser().data, null); */ export const useMessageEventState = ( eventType: typeof MessageEvent, selector: (event: T) => S, initial: S | (() => S) ): S => { const [ value, setValue ] = useState(initial); const selectorRef = useRef(selector); useLayoutEffect(() => { selectorRef.current = selector; }); const handler = useCallback((event: T) => { setValue(selectorRef.current(event)); }, []); useMessageEvent(eventType, handler); return value; };