Skip to content

hook syncpreferencestofilters

Paulo Gomes da Cruz Junior edited this page Jun 16, 2026 · 3 revisions

🔄 useSyncPreferencesToFilters Hook

Overview

useSyncPreferencesToFilters is a custom React hook that reactively syncs user preferences into filter state using a declarative mapping dictionary and an optional transform function. When the user's stored preferences change, only the relevant mapped fields are updated in the filter state — untracked preferences and manually set filter values are left untouched.

This hook is particularly useful when filter defaults should be driven by user preferences (e.g., a preferred district, previously selected client), ensuring the UI automatically reflects the user's saved choices without manual wiring.

🧪 Usage Example

import { useState } from 'react';
import useSyncPreferencesToFilters from '@/hooks/useSyncPreferencesToFilters';

type Filters = {
  clientNumbers: string[];
  district: string;
  search: string;
};

const FilteredPage = () => {
  const [filters, setFilters] = useState<Filters>({
    clientNumbers: [],
    district: '',
    search: '',
  });

  // Map preference keys to filter keys, with an optional transform
  useSyncPreferencesToFilters(
    setFilters,
    {
      selectedClient: 'clientNumbers',
      selectedDistrict: 'district',
    },
    (prefKey, prefValue) =>
      prefKey === 'selectedClient' ? [prefValue as string] : (prefValue as string),
  );

  return <FilterPanel filters={filters} onChange={setFilters} />;
};

In this example, when the user's selectedClient preference changes, it is wrapped in an array and set as clientNumbers. The selectedDistrict preference maps directly to district. The search filter is not affected.

🔍 Implementation Details

  • Preference Source: Reads from the usePreference context, which provides the current userPreference object.
  • Change Detection: Compares the current preference object with the previous one (tracked via a ref) using deep equality (isEqual from lodash). Only keys that actually changed are considered.
  • Relevant Filtering: Of the changed keys, only those present in the mapping dictionary trigger a filter update.
  • Null/Undefined Handling: If a tracked preference changes to null or undefined, the filter is not updated — the previous filter value is preserved. Empty strings are still applied.
  • Transform Function: An optional transform callback (prefKey, prefValue) => filterValue lets you reshape the preference value before it's set on the filter (e.g., wrapping a string into an array).
  • Non-Destructive: Only the mapped filter keys are updated; all other filter values are preserved via a shallow merge.

📦 Signature & Types

function useSyncPreferencesToFilters<T, PrefKeys extends string>(
  setFilters: React.Dispatch<React.SetStateAction<T>>,
  mapping: Record<PrefKeys, keyof T>,
  transform?: (prefKey: PrefKeys, prefValue: unknown) => T[keyof T]
): void;
  • setFilters: The React state setter for the filter object.
  • mapping: A record mapping preference keys to filter keys (e.g., { selectedDistrict: 'district' }).
  • transform: Optional function to transform a preference value before applying it to the filter.
  • Returns: Nothing — side-effect only.

💡 Why It Matters

User preferences and filter state often overlap — a user's preferred district or client should pre-populate relevant filters. useSyncPreferencesToFilters decouples preference management from filter logic, making it easy to keep filter defaults in sync with user settings without scattering preference-reading code across components.


For more hooks and context utilities, see the contexts-and-hooks documentation.

Waste Plus Wiki

Home

Architecture

Codes

Decisions

Knowledge Base

Development

Changes

Clone this wiki locally