import { ReactNode, createContext, useState, useMemo, Dispatch, SetStateAction, useEffect, useContext, } from "react"; import { useMeasure } from "react-use"; interface BannerInstance { id: string; height: number; } const BannerContext = createContext< [BannerInstance[], Dispatch>] >(null as any); export function BannerContextProvider(props: { children: ReactNode }) { const [state, setState] = useState([]); const memod = useMemo< [BannerInstance[], Dispatch>] >(() => [state, setState], [state]); return ( {props.children} ); } export function useBanner(id: string) { const [ref, { height }] = useMeasure(); // eslint-disable-next-line @typescript-eslint/no-unused-vars const [_, set] = useContext(BannerContext); useEffect(() => { set((v) => [...v, { id, height: 0 }]); set((value) => { const v = value.find((item) => item.id === id); if (v) { v.height = height; } return value; }); return () => { set((v) => v.filter((item) => item.id !== id)); }; }, [height, id, set]); return [ref]; } export function useBannerSize() { const [val] = useContext(BannerContext); return val.reduce((a, v) => a + v.height, 0); }