# react-patterns > Modern React patterns for React 19. Hooks, state management, component composition, performance optimization. Use when building React components. - Author: bruxaodev - Repository: LimaTechnologies/admin-telegram-bot - Version: 20260202030708 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/LimaTechnologies/admin-telegram-bot - Web: https://mule.run/skillshub/@@LimaTechnologies/admin-telegram-bot~react-patterns:20260202030708 --- --- name: react-patterns description: Modern React patterns for React 19. Hooks, state management, component composition, performance optimization. Use when building React components. allowed-tools: Read, Write, Edit, Grep, Glob --- # React Patterns - Modern Component Architecture ## Purpose Expert guidance for React 19 patterns: - **Component Design** - Composition over inheritance - **State Management** - Local, context, and server state - **Performance** - Memoization and optimization - **Hooks** - Built-in and custom hooks - **TypeScript** - Proper typing patterns --- ## Component Patterns ### 1. Compound Components ```tsx // Composable API for complex UIs interface TabsContextValue { activeTab: string; setActiveTab: (id: string) => void; } const TabsContext = createContext(null); function Tabs({ children, defaultTab }: { children: ReactNode; defaultTab: string }) { const [activeTab, setActiveTab] = useState(defaultTab); return (
{children}
); } function TabList({ children }: { children: ReactNode }) { return (
{children}
); } function Tab({ id, children }: { id: string; children: ReactNode }) { const context = useContext(TabsContext); if (!context) throw new Error('Tab must be used within Tabs'); return ( ); } function TabPanel({ id, children }: { id: string; children: ReactNode }) { const context = useContext(TabsContext); if (!context) throw new Error('TabPanel must be used within Tabs'); if (context.activeTab !== id) return null; return
{children}
; } // Usage Home Settings Home content Settings content ; ``` ### 2. Render Props Pattern ```tsx interface MousePosition { x: number; y: number; } function MouseTracker({ render }: { render: (pos: MousePosition) => ReactNode }) { const [position, setPosition] = useState({ x: 0, y: 0 }); useEffect(() => { const handleMove = (e: MouseEvent) => { setPosition({ x: e.clientX, y: e.clientY }); }; window.addEventListener('mousemove', handleMove); return () => window.removeEventListener('mousemove', handleMove); }, []); return <>{render(position)}; } // Usage (
Mouse: {x}, {y}
)} />; ``` ### 3. HOC (Higher-Order Component) ```tsx function withAuth

(Component: ComponentType

) { return function AuthenticatedComponent(props: P) { const { user, isLoading } = useAuth(); if (isLoading) return ; if (!user) return ; return ; }; } // Usage const ProtectedDashboard = withAuth(Dashboard); ``` --- ## Hooks Patterns ### Custom Hooks ```tsx // useLocalStorage - Persist state function useLocalStorage(key: string, initialValue: T) { const [storedValue, setStoredValue] = useState(() => { if (typeof window === 'undefined') return initialValue; try { const item = window.localStorage.getItem(key); return item ? JSON.parse(item) : initialValue; } catch { return initialValue; } }); const setValue = useCallback( (value: T | ((val: T) => T)) => { setStoredValue((prev) => { const valueToStore = value instanceof Function ? value(prev) : value; window.localStorage.setItem(key, JSON.stringify(valueToStore)); return valueToStore; }); }, [key] ); return [storedValue, setValue] as const; } // useDebounce - Debounced value function useDebounce(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { const handler = setTimeout(() => setDebouncedValue(value), delay); return () => clearTimeout(handler); }, [value, delay]); return debouncedValue; } // useAsync - Async operation state function useAsync(asyncFunction: () => Promise, deps: unknown[] = []) { const [state, setState] = useState<{ data: T | null; loading: boolean; error: Error | null; }>({ data: null, loading: true, error: null, }); useEffect(() => { let mounted = true; setState((s) => ({ ...s, loading: true })); asyncFunction() .then((data) => mounted && setState({ data, loading: false, error: null })) .catch((error) => mounted && setState({ data: null, loading: false, error })); return () => { mounted = false; }; }, deps); return state; } ``` --- ## State Management ### 1. useReducer for Complex State ```tsx type State = { items: Item[]; loading: boolean; error: string | null; }; type Action = | { type: 'FETCH_START' } | { type: 'FETCH_SUCCESS'; payload: Item[] } | { type: 'FETCH_ERROR'; payload: string } | { type: 'ADD_ITEM'; payload: Item } | { type: 'REMOVE_ITEM'; payload: string }; function reducer(state: State, action: Action): State { switch (action.type) { case 'FETCH_START': return { ...state, loading: true, error: null }; case 'FETCH_SUCCESS': return { ...state, loading: false, items: action.payload }; case 'FETCH_ERROR': return { ...state, loading: false, error: action.payload }; case 'ADD_ITEM': return { ...state, items: [...state.items, action.payload] }; case 'REMOVE_ITEM': return { ...state, items: state.items.filter((i) => i.id !== action.payload) }; default: return state; } } ``` ### 2. Context for Global State ```tsx interface AppContextValue { user: User | null; theme: 'light' | 'dark'; setTheme: (theme: 'light' | 'dark') => void; } const AppContext = createContext(undefined); export function AppProvider({ children }: { children: ReactNode }) { const [theme, setTheme] = useState<'light' | 'dark'>('light'); const { data: user } = useUser(); const value = useMemo(() => ({ user, theme, setTheme }), [user, theme]); return {children}; } export function useApp() { const context = useContext(AppContext); if (!context) throw new Error('useApp must be used within AppProvider'); return context; } ``` --- ## Performance Optimization ### 1. Memoization ```tsx // memo - Prevent re-renders const ExpensiveList = memo(function ExpensiveList({ items }: { items: Item[] }) { return (

); }); // useMemo - Expensive calculations function Dashboard({ data }: { data: DataPoint[] }) { const processedData = useMemo(() => { return data.map((d) => ({ ...d, computed: expensiveCalculation(d) })); }, [data]); return ; } // useCallback - Stable function references function Parent() { const [count, setCount] = useState(0); const handleClick = useCallback(() => { setCount((c) => c + 1); }, []); return ; } ``` ### 2. Code Splitting ```tsx import { lazy, Suspense } from 'react'; const HeavyComponent = lazy(() => import('./HeavyComponent')); function App() { return ( }> ); } ``` --- ## TypeScript Patterns ### Props Types ```tsx // Discriminated unions for variants type ButtonProps = { variant: 'primary'; onClick: () => void } | { variant: 'link'; href: string }; function Button(props: ButtonProps) { if (props.variant === 'link') { return Link; } return ; } // Generic components interface ListProps { items: T[]; renderItem: (item: T) => ReactNode; keyExtractor: (item: T) => string; } function List({ items, renderItem, keyExtractor }: ListProps) { return (
    {items.map((item) => (
  • {renderItem(item)}
  • ))}
); } ``` --- ## Agent Integration This skill is used by: - **react-expert** subagent - **render-optimizer** for performance issues - **ui-mobile/tablet/desktop** for component patterns --- ## FORBIDDEN 1. **Class components** - Use function components 2. **Prop drilling** - Use context or composition 3. **Inline objects/functions in JSX** - Causes re-renders 4. **useEffect for derived state** - Use useMemo 5. **Mutating state directly** - Always use setState/dispatch --- ## Version - **v1.0.0** - Initial implementation based on React 19 patterns