import { useCallback, useReducer, createContext, useContext } from "react"; import * as React from "react"; import { Item } from "../../../types"; import { Marker, Popup } from "leaflet"; type LeafletRef = { item: Item, marker: Marker, popup: Popup } type ActionType = | { type: "ADD_MARKER"; item: Item, marker: Marker } | { type: "ADD_POPUP"; item: Item, popup: Popup } ; type UseLeafletRefsManagerResult = ReturnType; const LeafletRefsContext = createContext({ leafletRefs: {}, addMarker: () => { }, addPopup: () => { }, }); function useLeafletRefsManager(initialLeafletRefs: {}): { leafletRefs: Record; // eslint-disable-next-line no-unused-vars addMarker: (item: Item, marker: Marker) => void; // eslint-disable-next-line no-unused-vars addPopup: (item: Item, popup: Popup) => void; } { const [leafletRefs, dispatch] = useReducer((state: Record, action: ActionType) => { switch (action.type) { case "ADD_MARKER": return { ...state, [action.item.id]: { ...state[action.item.id], marker: action.marker, item: action.item }} case "ADD_POPUP": return { ...state, [action.item.id]: { ...state[action.item.id], popup: action.popup, item: action.item }} default: throw new Error(); } }, initialLeafletRefs); const addMarker = useCallback((item: Item, marker: Marker) => { dispatch({ type: "ADD_MARKER", item, marker }); }, []); const addPopup = useCallback((item: Item, popup: Popup) => { dispatch({ type: "ADD_POPUP", item, popup }); }, []); return { leafletRefs, addMarker, addPopup }; } export const LeafletRefsProvider: React.FunctionComponent<{ initialLeafletRefs: {}, children?: React.ReactNode }> = ({ initialLeafletRefs, children }) => ( {children} ); export const useLeafletRefs = (): Record => { const { leafletRefs } = useContext(LeafletRefsContext); return leafletRefs; }; export const useAddMarker = (): UseLeafletRefsManagerResult["addMarker"] => { const { addMarker } = useContext(LeafletRefsContext); return addMarker; }; export const useAddPopup = (): UseLeafletRefsManagerResult["addPopup"] => { const { addPopup } = useContext(LeafletRefsContext); return addPopup; };