5180 fichiers 38.5 Mo 0 téléchargements 199 vues mis à jour il y a 5 heures ui
nitro-v36-with-renderer-v36 / src / hooks / events / useMessageEventReducer.ts
useMessageEventReducer.ts 1.9 Ko Télécharger le fichier
import { GetCommunication, IMessageEvent, MessageEvent } from '@octane/renderer';
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';

/**
 * Reducer companion of useMessageEventState for the server message
 * channel. Accepts either a single event type or an array of event types
 * that all collapse into the same state slice — typical for streams where
 * different composers update the same shape (e.g. furniture list +
 * add/update + remove all maintain one GroupItem[]).
 *
 *   const groupItems = useMessageEventReducer<GroupItem[], A | B | C>(
 *       [ParserA, ParserB, ParserC],
 *       (state, event) => {
 *           if (event instanceof ParserA) return applyA(state, event);
 *           if (event instanceof ParserB) return applyB(state, event);
 *           return state;
 *       },
 *       []
 *   );
 *
 * Closure stability via reducerRef refreshed in commit phase.
 */
export const useMessageEventReducer = <S, T extends IMessageEvent>(
    eventType: typeof MessageEvent | (typeof MessageEvent)[],
    reducer: (state: S, event: T) => S,
    initial: S | (() => S)
): S => {
    const [value, setValue] = useState<S>(initial);
    const reducerRef = useRef(reducer);

    useLayoutEffect(() => {
        reducerRef.current = reducer;
    });

    const handler = useCallback((event: T) => {
        setValue((prev) => reducerRef.current(prev, event));
    }, []);

    const types = useMemo(() => (Array.isArray(eventType) ? eventType : [eventType]), [eventType]);

    useEffect(() => {
        const communication = GetCommunication();

        const registered = types.map((t) => {
            //@ts-ignore
            const event = new t(handler);

            communication.registerMessageEvent(event);

            return event;
        });

        return () => {
            for (const event of registered) communication.removeMessageEvent(event);
        };
    }, [types, handler]);

    return value;
};
15Sujets
1Dépôts
20Membres
2En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser