Separation of Concerns
Each component has a single responsibility with clear interfaces
Master advanced React development patterns, performance optimization techniques, and enterprise-level code organization strategies used in the React admin template.
React 19 TypeScript Strict Performance Enterprise ReadyThe template uses strict TypeScript configuration for maximum type safety and code quality:
{ "compilerOptions": { "target": "ES2022", "lib": ["ES2022", "DOM", "DOM.Iterable"], "module": "ESNext", "moduleResolution": "bundler", "jsx": "react-jsx",
/* Strict type-checking options */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true, "erasableSyntaxOnly": true,
/* Module resolution */ "baseUrl": ".", "paths": { "@/*": ["./src/*"] } }, "include": ["src", "globals.d.ts"]}
Define comprehensive interfaces for all data structures:
// API Response patternsexport interface ApiResponse<T> { data: T message?: string success: boolean code?: number}
// Pagination with strict typingexport interface PaginatedResponse<T> { data: T[] total: number page: number limit: number totalPages: number}
// User entity with role-based typingexport interface User { id: string name: string email: string avatar?: string role: Role status: Status createdAt: string updatedAt: string}
// Component props with strict structureexport interface BaseComponentProps { className?: string children?: React.ReactNode}
// Navigation structure typingexport interface NavItem { title: string url: string icon?: React.ComponentType isActive?: boolean children?: NavItem[]}
The template implements optimized custom hooks with proper dependency management:
import { useState, useEffect, useMemo } from "react"
/** * Optimized media query hook with memoized values */export function useMediaQuery() { // Core media query states const isMobile = useMediaQueryCore('(max-width: 767px)') const isTablet = useMediaQueryCore('(min-width: 768px) and (max-width: 1279px)') const isDesktop = useMediaQueryCore('(min-width: 1280px)')
// Memoized computed values for performance const canShowThreeColumns = useMemo(() => isDesktop, [isDesktop]) const shouldUseFullScreen = useMemo(() => isMobile, [isMobile]) const canShowTwoColumns = useMemo(() => isTablet || isDesktop, [isTablet, isDesktop] )
return { isMobile, isTablet, isDesktop, // Layout helpers canShowThreeColumns, shouldUseFullScreen, canShowTwoColumns, }}
function useMediaQueryCore(query: string): boolean { const [matches, setMatches] = useState<boolean>(false)
useEffect(() => { const mediaQuery = window.matchMedia(query)
setMatches(mediaQuery.matches)
const handleChange = (event: MediaQueryListEvent) => { setMatches(event.matches) }
mediaQuery.addEventListener('change', handleChange) return () => mediaQuery.removeEventListener('change', handleChange) }, [query])
return matches}
Robust localStorage hook with error handling and type safety:
import { useState } from 'react'
export function useLocalStorage<T>( key: string, initialValue: T): [T, (value: T | ((val: T) => T)) => void] { // Lazy initial state to avoid reading localStorage on every render const [storedValue, setStoredValue] = useState<T>(() => { try { const item = window.localStorage.getItem(key) return item ? JSON.parse(item) : initialValue } catch (error) { console.error(`Error reading localStorage key "${key}":`, error) return initialValue } })
// Wrapper function to persist updates to localStorage const setValue = (value: T | ((val: T) => T)) => { try { // Support function updates like useState const valueToStore = value instanceof Function ? value(storedValue) : value setStoredValue(valueToStore) window.localStorage.setItem(key, JSON.stringify(valueToStore)) } catch (error) { console.error(`Error setting localStorage key "${key}":`, error) } }
return [storedValue, setValue]}
Complex table hook with validation and memoization:
import { useEffect, useMemo, useState, useCallback, useRef } from 'react'import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, getExpandedRowModel } from '@tanstack/react-table'import type { ColumnFiltersState, SortingState, VisibilityState, ExpandedState } from '@tanstack/react-table'
// Comprehensive validation systemconst validateTableData = <T>(data: T[], options: TableValidationOptions = {}): ValidationResult => { const errors: string[] = [] const warnings: string[] = []
if (!Array.isArray(data)) { errors.push('Data must be an array') return { isValid: false, errors, warnings } }
if (data.length === 0) { warnings.push('No data provided') }
if (options.strictMode) { // Check for consistent data structure if (data.length > 0) { const firstRowKeys = Object.keys(data[0] || {}) const inconsistentRows = data.slice(1).filter(row => { const rowKeys = Object.keys(row || {}) return rowKeys.length !== firstRowKeys.length || !firstRowKeys.every(key => key in (row || {})) })
if (inconsistentRows.length > 0) { warnings.push(`${inconsistentRows.length} rows have inconsistent structure`) } } }
return { isValid: errors.length === 0, errors, warnings }}
const validateColumns = <T = any>(columns: ColumnDef<T, unknown>[], options: TableValidationOptions = {}): ValidationResult => { const errors: string[] = [] const warnings: string[] = []
if (!Array.isArray(columns) || columns.length === 0) { errors.push('At least one column must be defined') return { isValid: false, errors, warnings } }
// Check for duplicate column IDs const columnIds = columns.map(col => { if ('id' in col && col.id) return col.id if ('accessorKey' in col && col.accessorKey) return String(col.accessorKey) return undefined }).filter(Boolean) const duplicates = columnIds.filter((id, index) => columnIds.indexOf(id) !== index)
if (duplicates.length > 0) { errors.push(`Duplicate column IDs found: ${[...new Set(duplicates)].join(', ')}`) }
return { isValid: errors.length === 0, errors, warnings }}
export function useTableInstance<T = any>( props: HiTableProps<T>, config: TableConfig = {}, validationOptions: TableValidationOptions = {}) { const [sorting, setSorting] = useState<SortingState>([]) const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]) const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({}) const [rowSelection, setRowSelection] = useState({}) const [expanded, setExpanded] = useState<ExpandedState>({}) const [validationErrors, setValidationErrors] = useState<string[]>([])
// Performance: Use stable dependencies for memoization const dataLength = props.data.length const columnsLength = props.columns.length const isStrictMode = validationOptions.strictMode
// Memoized validation to prevent unnecessary recalculations const validation = useMemo(() => { const dataValidation = validateTableData(props.data, validationOptions) const columnValidation = validateColumns(props.columns, validationOptions)
return { data: dataValidation, columns: columnValidation, isValid: dataValidation.isValid && columnValidation.isValid, allErrors: [...dataValidation.errors, ...columnValidation.errors], allWarnings: [...dataValidation.warnings, ...columnValidation.warnings] } }, [props.data, props.columns, dataLength, columnsLength, isStrictMode])
// Update validation errors when validation changes useEffect(() => { setValidationErrors(validation.allErrors) if (validation.allWarnings.length > 0 && process.env.NODE_ENV === 'development') { console.warn('HiTable validation warnings:', validation.allWarnings) } }, [validation.allErrors, validation.allWarnings])
// Default configuration with comprehensive options const defaultConfig: TableConfig = useMemo(() => ({ pagination: { enabled: true, pageSize: 10, showPageInfo: true }, sorting: { enabled: true, multiSort: false }, filtering: { enabled: true, searchable: true }, columnVisibility: { enabled: true, buttonText: 'Columns' }, rowSelection: { enabled: false }, expandable: { enabled: false }, styling: { compact: false }, emptyState: { message: 'No results found.' }, loading: { enabled: false, message: 'Loading...' }, }), [])
// Memoized configuration object const mergedConfig = useMemo(() => ({ ...defaultConfig, ...config, pagination: { ...defaultConfig.pagination, ...config.pagination }, sorting: { ...defaultConfig.sorting, ...config.sorting }, filtering: { ...defaultConfig.filtering, ...config.filtering }, columnVisibility: { ...defaultConfig.columnVisibility, ...config.columnVisibility }, rowSelection: { ...defaultConfig.rowSelection, ...config.rowSelection }, expandable: { ...defaultConfig.expandable, ...config.expandable }, styling: { ...defaultConfig.styling, ...config.styling }, emptyState: { ...defaultConfig.emptyState, ...config.emptyState }, loading: { ...defaultConfig.loading, ...config.loading }, }), [config, defaultConfig])
// Stable table configuration const tableConfig = useMemo(() => ({ data: validation.isValid ? props.data : [], columns: validation.isValid ? props.columns : [], getCoreRowModel: getCoreRowModel(), // Conditional feature enabling ...(mergedConfig.pagination?.enabled && { getPaginationRowModel: getPaginationRowModel(), }), ...(mergedConfig.sorting?.enabled && { getSortedRowModel: getSortedRowModel(), enableMultiSort: mergedConfig.sorting.multiSort, }), ...(mergedConfig.filtering?.enabled && { getFilteredRowModel: getFilteredRowModel(), }), ...(mergedConfig.expandable?.enabled && { getExpandedRowModel: getExpandedRowModel(), }), ...(mergedConfig.rowSelection?.enabled && { enableRowSelection: true, }), initialState: { ...(mergedConfig.pagination?.enabled && { pagination: { pageSize: mergedConfig.pagination.pageSize || 10 }, }), }, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, onColumnVisibilityChange: setColumnVisibility, onRowSelectionChange: setRowSelection, onExpandedChange: setExpanded, state: { sorting, columnFilters, columnVisibility, rowSelection, expanded, }, }), [ validation.isValid, props.data, props.columns, mergedConfig, sorting, columnFilters, columnVisibility, rowSelection, expanded ])
const table = useReactTable(tableConfig)
// Performance: Reset pagination only when data actually changes const previousDataRef = useRef(props.data) const setPageIndexRef = useRef(table.setPageIndex)
useEffect(() => { setPageIndexRef.current = table.setPageIndex }, [table.setPageIndex])
useEffect(() => { if (mergedConfig.pagination?.enabled && previousDataRef.current !== props.data) { setPageIndexRef.current(0) previousDataRef.current = props.data } }, [props.data, mergedConfig.pagination?.enabled])
// Exposed methods for external control const resetFilters = () => setColumnFilters([]) const resetSelection = () => setRowSelection({}) const resetSorting = () => setSorting([]) const resetAll = () => { resetFilters() resetSelection() resetSorting() setExpanded({}) } const resetValidation = useCallback(() => setValidationErrors([]), [])
return { table, config: mergedConfig, // State for direct access sorting, columnFilters, columnVisibility, rowSelection, expanded, // Validation validation, validationErrors, // Methods resetFilters, resetSelection, resetSorting, resetAll, resetValidation, }}
The template uses compound components for flexible, reusable UI:
Separation of Concerns
Each component has a single responsibility with clear interfaces
Composition over Inheritance
Components are composed together rather than extended
Prop Drilling Avoidance
Context and custom hooks prevent deep prop passing
Robust error handling with TypeScript:
import React from 'react'
interface Props { children: React.ReactNode fallback?: React.ComponentType<{ error: Error }>}
interface State { hasError: boolean error: Error | null}
export class ErrorBoundary extends React.Component<Props, State> { constructor(props: Props) { super(props) this.state = { hasError: false, error: null } }
static getDerivedStateFromError(error: Error): State { return { hasError: true, error } }
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { console.error('Error boundary caught an error:', error, errorInfo) }
render() { if (this.state.hasError && this.state.error) { const Fallback = this.props.fallback return Fallback ? <Fallback error={this.state.error} /> : ( <div className="p-4 border border-destructive/50 rounded-lg bg-destructive/5"> <h2 className="font-semibold text-destructive">Something went wrong</h2> <p className="text-sm text-muted-foreground mt-1"> {this.state.error.message} </p> </div> ) }
return this.props.children }}
Advanced form validation with React Hook Form and Zod:
import { useForm } from 'react-hook-form'import { zodResolver } from '@hookform/resolvers/zod'import type { z } from 'zod'
export function useFormValidation({ fields, schema, defaultValues = {}, onChange}: UseFormValidationProps) { // Generate default values from fields if not provided const generateDefaultValues = (): FormValues => { const values: FormValues = { ...defaultValues }
fields.forEach(field => { if (values[field.name] === undefined) { switch (field.type) { case 'checkbox': if ('options' in field && field.options) { values[field.name] = [] } else { values[field.name] = false } break case 'switch': values[field.name] = false break case 'slider': if ('config' in field && field.config.defaultValue) { values[field.name] = field.config.defaultValue } else if ('config' in field) { values[field.name] = [field.config.min] } break case 'select': if ('multiple' in field && field.multiple) { values[field.name] = [] } else { values[field.name] = '' } break case 'datePicker': if ('config' in field && field.config?.mode === 'multiple') { values[field.name] = [] } else if ('config' in field && field.config?.mode === 'range') { values[field.name] = { from: undefined, to: undefined } } else { values[field.name] = undefined } break default: values[field.name] = '' } } })
return values }
const form = useForm({ resolver: schema ? zodResolver(schema as any) : undefined, defaultValues: generateDefaultValues(), mode: 'onChange' })
const { watch, setValue, reset, formState } = form const watchedValues = watch()
// Handle field changes - no useCallback needed for this implementation const handleFieldChange = (name: string, value: FormValue) => { setValue(name, value, { shouldValidate: true, shouldDirty: true })
if (onChange) { const allValues = { ...watchedValues, [name]: value } onChange(name, value, allValues) } }
// Get visible fields based on conditions const getVisibleFields = () => { return fields.filter(field => { if (!field.condition) return true return field.condition(watchedValues) }) }
// Reset form with new values const resetForm = (values?: FormValues) => { reset(values || generateDefaultValues()) }
return { form, watchedValues, handleFieldChange, getVisibleFields, resetForm, isSubmitting: formState.isSubmitting, isDirty: formState.isDirty, isValid: formState.isValid, errors: formState.errors }}
The template uses Zustand for lightweight, type-safe state management:
import { create } from 'zustand'import { persist, createJSONStorage } from 'zustand/middleware'
// UI State Managementinterface UIState { sidebarCollapsed: boolean fixedSidebarVisible: boolean layoutMode: LayoutMode expandedMenuItems: string[] // Actions setSidebarCollapsed: (collapsed: boolean) => void toggleSidebar: () => void toggleMenuExpand: (menuTitle: string) => void}
export const useUIStore = create<UIState>()( persist( (set, get) => ({ // Initial state sidebarCollapsed: false, fixedSidebarVisible: false, layoutMode: 'sidebar' as LayoutMode, expandedMenuItems: [],
// Synchronous actions setSidebarCollapsed: (collapsed) => set({ sidebarCollapsed: collapsed }),
// Complex state updates toggleMenuExpand: (menuTitle) => set((state) => ({ expandedMenuItems: state.expandedMenuItems.includes(menuTitle) ? state.expandedMenuItems.filter((item) => item !== menuTitle) : [...state.expandedMenuItems, menuTitle] })),
// Computed actions using get() toggleSidebar: () => set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })), }), { name: 'ui-storage', storage: createJSONStorage(() => localStorage), // Selective persistence partialize: (state) => ({ layoutMode: state.layoutMode, sidebarCollapsed: state.sidebarCollapsed }), } ))
Advanced theme management with system preference detection:
export const useThemeStore = create<ThemeState>()( persist( (set, get) => ({ theme: "system", resolvedTheme: "light",
setTheme: (theme: Theme) => { const resolvedTheme = applyTheme(theme) set({ theme, resolvedTheme }) },
initialize: () => { const { theme } = get() const resolvedTheme = applyTheme(theme) set({ resolvedTheme })
// System theme change listener if (typeof window !== 'undefined') { const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)') const handleChange = () => { const currentTheme = get().theme if (currentTheme === 'system') { const newResolvedTheme = getSystemTheme() const root = window.document.documentElement root.classList.remove("light", "dark") root.classList.add(newResolvedTheme) set({ resolvedTheme: newResolvedTheme }) } }
mediaQuery.addEventListener('change', handleChange) } }, }), { name: 'admin-theme', partialize: (state) => ({ theme: state.theme }), } ))
Organize exports for better maintainability:
// Store exportsexport { useUIStore } from './uiStore'export { useThemeColorStore } from './themeColorStore'export { useThemeStore, useTheme } from './themeStore'
// Hook exportsexport { useIsMobile, useIsDevice } from './useMobile'export { useLocalStorage } from './useLocalStorage'export { useMediaQuery, useMediaQueryCore } from './useMediaQuery'
// Component exports with type re-exportsexport { HiTable } from './HiTable'export type { HiTableProps, TableConfig } from './types'
Clean, type-safe utility functions:
import { clsx, type ClassValue } from "clsx"import { twMerge } from "tailwind-merge"
// Tailwind class utility with proper typingexport function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs))}
// Number formatting utilitiesexport function formatNumber(value: number): string { return new Intl.NumberFormat('en-US').format(value)}
export function formatCurrency(value: number): string { return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, }).format(value)}
// Color validation utilitiesexport function isValidHexColor(color: string): boolean { if (!color) return false
const hex = color.startsWith('#') ? color.slice(1) : color const hexPattern = /^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/ return hexPattern.test(hex)}
// Name utility with proper error handlingexport function getInitials(name: string, maxInitials: number = 2): string { if (!name || typeof name !== 'string') return ''
return name .trim() .split(' ') .filter(word => word.length > 0) .slice(0, maxInitials) .map(word => word[0]) .join('') .toUpperCase()}
Memoization Strategy
useMemo
for expensive calculationsuseCallback
for stable function referencesBundle Optimization
State Management
Component Optimization
Comprehensive linting setup for code quality:
import js from '@eslint/js'import globals from 'globals'import reactHooks from 'eslint-plugin-react-hooks'import reactRefresh from 'eslint-plugin-react-refresh'import tseslint from 'typescript-eslint'import { globalIgnores } from 'eslint/config'
export default tseslint.config([ globalIgnores(['dist']), { files: ['**/*.{ts,tsx}'], extends: [ js.configs.recommended, tseslint.configs.recommended, reactHooks.configs['recommended-latest'], reactRefresh.configs.vite, ], languageOptions: { ecmaVersion: 2020, globals: globals.browser, }, },])
Unit Tests
Test individual functions and component logic in isolation
Integration Tests
Test component interactions and hook behaviors
Accessibility Tests
Ensure WCAG compliance and keyboard navigation
Performance Tests
Monitor rendering performance and memory usage
Enable development debugging utilities:
// Development-only debugging utilitiesif (process.env.NODE_ENV === 'development') { // Global debug helpers window.debugState = { ui: () => useUIStore.getState(), theme: () => useThemeStore.getState(), themeColor: () => useThemeColorStore.getState(), }
// Performance monitoring window.measureRender = (componentName: string) => { performance.mark(`${componentName}-start`) return () => { performance.mark(`${componentName}-end`) performance.measure(componentName, `${componentName}-start`, `${componentName}-end`) } }}
TypeScript Configuration
Component Design
Performance
State Management
Code Quality
Master these React development patterns to build scalable, maintainable, and high-performance applications! 🚀