"use client"; import type { PropsWithChildren } from "react"; import { createContext, useContext, useEffect, useState } from "react"; type Data = Record< string, { data: Record | undefined; isReady: boolean; } >; interface GlobalItemServerDataContext { setItemServerData: (id: string, data: Record | undefined) => void; data: Data; initalItemIds: string[]; } const GlobalItemServerDataContext = createContext(null); interface Props { initalItemIds: string[]; } export const GlobalItemServerDataProvider = ({ children, initalItemIds }: PropsWithChildren) => { const [data, setData] = useState({}); const setItemServerData = (id: string, itemData: Record | undefined) => { setData((prev) => ({ ...prev, [id]: { data: itemData, isReady: true, }, })); }; return ( {children} ); }; export const useServerDataFor = (id: string) => { const context = useContext(GlobalItemServerDataContext); if (!context) { throw new Error("GlobalItemServerDataProvider is required"); } // When the item is not in the initial list, it means the data can not come from the server if (!context.initalItemIds.includes(id)) { return { data: undefined, isReady: true, }; } return context.data[id]; }; export const useServerDataInitializer = (id: string, serverData: Record | undefined) => { const context = useContext(GlobalItemServerDataContext); if (!context) { throw new Error("GlobalItemServerDataProvider is required"); } useEffect(() => { context.setItemServerData(id, serverData); }, []); };