perf: memoize expensive list computations + memo on grid/list items

Results.tsx:
- useMemo: filter + sort in one pass (was 7 separate array iterations per render)
- useMemo: platform/maison/future/missingData counts in single for-loop
- Fix: move queryClient.invalidateQueries from render body into useEffect

Properties.tsx:
- useMemo: wrap applyFilters() call (was full copy+sort on every render)
- useMemo: compute matchReady/criticalGaps/lowConfidence/staleOrOutdated/
  allMissingFields in a single for-loop (was 5 separate filter passes)

ReminderFeed.tsx:
- useMemo: wrap applyFilters() call
- useCallback: resetFilters (passed to ReminderEmptyState)

PropertyIntelligenceCard, ReminderListRow:
- React.memo: grid/list items no longer re-render when unrelated parent
  state changes (e.g. selectedId, filter UI state)

tsc --noEmit passes with zero errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-24 01:53:03 +02:00
parent 86bdf142b4
commit ce67da73b3
5 changed files with 79 additions and 47 deletions
+10 -5
View File
@@ -1,3 +1,4 @@
import { useMemo, useCallback } from 'react'
import { Box, Typography } from '@mui/material'
import { useReminders } from '../../hooks/useReminders'
import { useShallow } from 'zustand/react/shallow'
@@ -43,17 +44,21 @@ export function ReminderFeed() {
setSearchQuery: s.setSearchQuery,
})))
if (isLoading) return <ReminderSkeleton />
const reminders = data ?? []
const filtered = applyFilters(reminders, filterType, filterStatus, filterPriority, searchQuery)
function resetFilters() {
const filtered = useMemo(
() => applyFilters(reminders, filterType, filterStatus, filterPriority, searchQuery),
[reminders, filterType, filterStatus, filterPriority, searchQuery],
)
const resetFilters = useCallback(() => {
setFilterType('ALL')
setFilterStatus('ALL')
setFilterPriority('ALL')
setSearchQuery('')
}
}, [setFilterType, setFilterStatus, setFilterPriority, setSearchQuery])
if (isLoading) return <ReminderSkeleton />
if (filtered.length === 0) {
return <ReminderEmptyState onReset={resetFilters} />