diff --git a/apps/client/src/components/citizen/pets/medical-records/manage-pet-medical-record-modal.tsx b/apps/client/src/components/citizen/pets/medical-records/manage-pet-medical-record-modal.tsx index bec2fa4e4..83a9aae6b 100644 --- a/apps/client/src/components/citizen/pets/medical-records/manage-pet-medical-record-modal.tsx +++ b/apps/client/src/components/citizen/pets/medical-records/manage-pet-medical-record-modal.tsx @@ -26,7 +26,7 @@ export function ManagePetMedicalRecordModal(props: Props) { const modalState = useModal(); const common = useTranslations("Common"); const t = useTranslations("MedicalRecords"); - const { currentPet } = usePetsState(); + const currentPet = usePetsState((state) => state.currentPet); function handleClose() { modalState.closeModal(ModalIds.ManagePetMedicalRecord); diff --git a/apps/client/src/components/citizen/pets/notes/manage-pet-note-modal.tsx b/apps/client/src/components/citizen/pets/notes/manage-pet-note-modal.tsx index 21a38000b..9ecad6ea9 100644 --- a/apps/client/src/components/citizen/pets/notes/manage-pet-note-modal.tsx +++ b/apps/client/src/components/citizen/pets/notes/manage-pet-note-modal.tsx @@ -24,7 +24,7 @@ export function ManagePetNoteModal(props: Props) { const common = useTranslations("Common"); const t = useTranslations("Pets"); const { state, execute } = useFetch(); - const { currentPet } = usePetsState(); + const currentPet = usePetsState((state) => state.currentPet); function handleClose() { modalState.closeModal(ModalIds.ManageNote); diff --git a/apps/client/src/components/citizen/pets/pet-information-card.tsx b/apps/client/src/components/citizen/pets/pet-information-card.tsx index f5e5e9815..e385731b4 100644 --- a/apps/client/src/components/citizen/pets/pet-information-card.tsx +++ b/apps/client/src/components/citizen/pets/pet-information-card.tsx @@ -23,7 +23,7 @@ import { useTranslations } from "use-intl"; export function PetInformationCard() { const t = useTranslations("Pets"); const { cad } = useAuth(); - const { currentPet } = usePetsState(); + const currentPet = usePetsState((state) => state.currentPet); const modalState = useModal(); const { state, execute } = useFetch(); const router = useRouter(); diff --git a/apps/client/src/components/leo/modals/NameSearchModal/tabs/vehicles-tab.tsx b/apps/client/src/components/leo/modals/NameSearchModal/tabs/vehicles-tab.tsx index 9432190bd..0a84f039d 100644 --- a/apps/client/src/components/leo/modals/NameSearchModal/tabs/vehicles-tab.tsx +++ b/apps/client/src/components/leo/modals/NameSearchModal/tabs/vehicles-tab.tsx @@ -13,7 +13,7 @@ export function NameSearchVehiclesTab() { const { DMV } = useFeatureEnabled(); const currentResult = useNameSearch((state) => state.currentResult); const modalState = useModal(); - const { setCurrentResult: setVehicleResult } = useVehicleSearch(); + const setVehicleResult = useVehicleSearch((state) => state.setCurrentResult); const tableState = useTableState(); function handlePlateClick(vehicle: VehicleSearchResult) { diff --git a/apps/client/src/components/leo/qualifications/ActiveUnitsQualificationsCard.tsx b/apps/client/src/components/leo/qualifications/ActiveUnitsQualificationsCard.tsx index d4d51e927..8523f0c6a 100644 --- a/apps/client/src/components/leo/qualifications/ActiveUnitsQualificationsCard.tsx +++ b/apps/client/src/components/leo/qualifications/ActiveUnitsQualificationsCard.tsx @@ -9,10 +9,11 @@ import type { import { useDebounce, useHoverDirty } from "react-use"; import { isUnitCombined, isUnitCombinedEmsFd } from "@snailycad/utils"; import useFetch from "lib/useFetch"; -import { create } from "zustand"; import { HoverCard, HoverCardContent, HoverCardTrigger, Loader } from "@snailycad/ui"; import type { GetUnitQualificationsByUnitIdData } from "@snailycad/types/api"; import dynamic from "next/dynamic"; +import { createWithEqualityFn } from "zustand/traditional"; +import { shallow } from "zustand/shallow"; const UnitQualificationsTable = dynamic( async () => (await import("./UnitQualificationsTable")).UnitQualificationsTable, @@ -33,10 +34,13 @@ interface CacheStore { setUnits(units: CacheStore["units"]): void; } -const useCacheStore = create((set) => ({ - units: {}, - setUnits: (units) => set({ units }), -})); +const useCacheStore = createWithEqualityFn( + (set) => ({ + units: {}, + setUnits: (units) => set({ units }), + }), + shallow, +); export function ActiveUnitsQualificationsCard({ canBeOpened = true, unit, children }: Props) { const { state, execute } = useFetch(); diff --git a/apps/client/src/hooks/shared/useSignal100.tsx b/apps/client/src/hooks/shared/useSignal100.tsx index 36db31e4e..7ef5501d1 100644 --- a/apps/client/src/hooks/shared/useSignal100.tsx +++ b/apps/client/src/hooks/shared/useSignal100.tsx @@ -6,15 +6,19 @@ import { useTranslations } from "use-intl"; import { useAudio } from "react-use"; import { useCall911State } from "state/dispatch/call-911-state"; import { Alert } from "@snailycad/ui"; -import { create } from "zustand"; +import { createWithEqualityFn } from "zustand/traditional"; +import { shallow } from "zustand/shallow"; -const useSignal100Store = create<{ +const useSignal100Store = createWithEqualityFn<{ playCount: number; setPlayCount(value: number): void; -}>()((set) => ({ - playCount: 0, - setPlayCount: (value: number) => set({ playCount: value }), -})); +}>()( + (set) => ({ + playCount: 0, + setPlayCount: (value: number) => set({ playCount: value }), + }), + shallow, +); const SIGNAL_100_SRC = "/sounds/signal100.mp3"; export function useSignal100() { diff --git a/apps/client/src/state/callsFiltersState.ts b/apps/client/src/state/callsFiltersState.ts index 68e10e5ea..a22601277 100644 --- a/apps/client/src/state/callsFiltersState.ts +++ b/apps/client/src/state/callsFiltersState.ts @@ -1,5 +1,6 @@ -import { create } from "zustand"; import type { Record, Citizen, MedicalRecord, RegisteredVehicle, Weapon } from "@snailycad/types"; +import { shallow } from "zustand/shallow"; +import { createWithEqualityFn } from "zustand/traditional"; export type CitizenWithVehAndWep = Citizen & { weapons: Weapon[]; @@ -25,19 +26,22 @@ interface CallFiltersState { setAssignedUnit(assignedUnit: string | null): void; } -export const useCallsFilters = create()((set) => ({ - showFilters: false, - setShowFilters: (showFilters) => set({ showFilters }), +export const useCallsFilters = createWithEqualityFn()( + (set) => ({ + showFilters: false, + setShowFilters: (showFilters) => set({ showFilters }), - search: "", - setSearch: (search) => set({ search }), + search: "", + setSearch: (search) => set({ search }), - assignedUnit: null, - setAssignedUnit: (assignedUnit) => set({ assignedUnit }), + assignedUnit: null, + setAssignedUnit: (assignedUnit) => set({ assignedUnit }), - department: null, - setDepartment: (department) => set({ department }), + department: null, + setDepartment: (department) => set({ department }), - division: null, - setDivision: (division) => set({ division }), -})); + division: null, + setDivision: (division) => set({ division }), + }), + shallow, +); diff --git a/apps/client/src/state/citizen/pets-state.ts b/apps/client/src/state/citizen/pets-state.ts index f86e84b32..a28cbdddf 100644 --- a/apps/client/src/state/citizen/pets-state.ts +++ b/apps/client/src/state/citizen/pets-state.ts @@ -1,12 +1,16 @@ import type { Pet } from "@snailycad/types"; -import { create } from "zustand"; +import { shallow } from "zustand/shallow"; +import { createWithEqualityFn } from "zustand/traditional"; interface PetsState { currentPet: Pet | null; setCurrentPet(pet: Pet): void; } -export const usePetsState = create()((set) => ({ - currentPet: null, - setCurrentPet: (pet) => set({ currentPet: pet }), -})); +export const usePetsState = createWithEqualityFn()( + (set) => ({ + currentPet: null, + setCurrentPet: (pet) => set({ currentPet: pet }), + }), + shallow, +); diff --git a/apps/client/src/state/mapState.ts b/apps/client/src/state/mapState.ts index acad8f861..50fd10ce9 100644 --- a/apps/client/src/state/mapState.ts +++ b/apps/client/src/state/mapState.ts @@ -1,7 +1,6 @@ import { ConnectionStatus } from "@snailycad/ui"; import { Socket } from "socket.io-client"; import { SmartSignMarker } from "types/map"; -import { create } from "zustand"; import { persist, createJSONStorage } from "zustand/middleware"; import { shallow } from "zustand/shallow"; import { createWithEqualityFn } from "zustand/traditional"; @@ -67,14 +66,17 @@ export const useDispatchMapState = createWithEqualityFn()( shallow, ); -export const useSocketStore = create()((set) => ({ - status: null, - setStatus(status) { - set({ status }); - }, +export const useSocketStore = createWithEqualityFn()( + (set) => ({ + status: null, + setStatus(status) { + set({ status }); + }, - socket: null, - setSocket(socket) { - set({ socket }); - }, -})); + socket: null, + setSocket(socket) { + set({ socket }); + }, + }), + shallow, +); diff --git a/apps/client/src/state/search/vehicle-search-state.ts b/apps/client/src/state/search/vehicle-search-state.ts index 71504345b..15d42afeb 100644 --- a/apps/client/src/state/search/vehicle-search-state.ts +++ b/apps/client/src/state/search/vehicle-search-state.ts @@ -1,5 +1,6 @@ import type { PostLeoSearchVehicleData } from "@snailycad/types/api"; -import { create } from "zustand"; +import { createWithEqualityFn } from "zustand/traditional"; +import { shallow } from "zustand/shallow"; export type VehicleSearchResult = NonNullable; @@ -8,7 +9,10 @@ interface VehicleSearchState { setCurrentResult(v: VehicleSearchResult | null | "initial"): void; } -export const useVehicleSearch = create()((set) => ({ - currentResult: "initial", - setCurrentResult: (v) => set({ currentResult: v }), -})); +export const useVehicleSearch = createWithEqualityFn()( + (set) => ({ + currentResult: "initial", + setCurrentResult: (v) => set({ currentResult: v }), + }), + shallow, +);