mirror of
https://github.com/jhbruhn/respira.git
synced 2026-01-27 10:23:41 +00:00
fix: Use shallow comparison in selector hooks to prevent infinite re-renders
The selectors were creating new object references on every call, causing Zustand's subscription system to detect changes and trigger infinite re-render loops. This was particularly evident in usePatternValidationFromStore. Solution: - Import useShallow from zustand/react/shallow - Wrap all selector hooks (usePatternCenter, useUploadedPatternCenter, useRotatedBounds, usePatternValidationFromStore) with useShallow - useShallow performs shallow comparison on returned objects, preventing re-renders when values haven't actually changed This follows the established pattern in the codebase where useShallow is already used extensively (App.tsx, FileUpload.tsx, etc). Co-authored-by: jhbruhn <1036566+jhbruhn@users.noreply.github.com>
This commit is contained in:
parent
6fbb3ebf1a
commit
bcb5ea1786
1 changed files with 14 additions and 8 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
|
import { useShallow } from "zustand/react/shallow";
|
||||||
import type { PesPatternData } from "../formats/import/pesImporter";
|
import type { PesPatternData } from "../formats/import/pesImporter";
|
||||||
import { onPatternDeleted } from "./storeEvents";
|
import { onPatternDeleted } from "./storeEvents";
|
||||||
import { calculatePatternCenter } from "../components/PatternCanvas/patternCanvasHelpers";
|
import { calculatePatternCenter } from "../components/PatternCanvas/patternCanvasHelpers";
|
||||||
|
|
@ -293,28 +294,33 @@ export const selectPatternValidation = (
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook to get pattern center (memoized)
|
* Hook to get pattern center (memoized with shallow comparison)
|
||||||
*/
|
*/
|
||||||
export const usePatternCenter = () => usePatternStore(selectPatternCenter);
|
export const usePatternCenter = () =>
|
||||||
|
usePatternStore(useShallow(selectPatternCenter));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook to get uploaded pattern center (memoized)
|
* Hook to get uploaded pattern center (memoized with shallow comparison)
|
||||||
*/
|
*/
|
||||||
export const useUploadedPatternCenter = () =>
|
export const useUploadedPatternCenter = () =>
|
||||||
usePatternStore(selectUploadedPatternCenter);
|
usePatternStore(useShallow(selectUploadedPatternCenter));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook to get rotated bounds (memoized)
|
* Hook to get rotated bounds (memoized with shallow comparison)
|
||||||
*/
|
*/
|
||||||
export const useRotatedBounds = () => usePatternStore(selectRotatedBounds);
|
export const useRotatedBounds = () =>
|
||||||
|
usePatternStore(useShallow(selectRotatedBounds));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook to get pattern validation result (requires machineInfo)
|
* Hook to get pattern validation result (requires machineInfo)
|
||||||
* Use this with caution as it requires external state
|
* Uses shallow comparison to prevent infinite re-renders from new object references
|
||||||
*/
|
*/
|
||||||
export const usePatternValidationFromStore = (
|
export const usePatternValidationFromStore = (
|
||||||
machineInfo: { maxWidth: number; maxHeight: number } | null,
|
machineInfo: { maxWidth: number; maxHeight: number } | null,
|
||||||
) => usePatternStore((state) => selectPatternValidation(state, machineInfo));
|
) =>
|
||||||
|
usePatternStore(
|
||||||
|
useShallow((state) => selectPatternValidation(state, machineInfo)),
|
||||||
|
);
|
||||||
|
|
||||||
// Subscribe to pattern deleted event.
|
// Subscribe to pattern deleted event.
|
||||||
// This subscription is intended to persist for the lifetime of the application,
|
// This subscription is intended to persist for the lifetime of the application,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue