react

React useReducer for complex state logic

useReducer manages state with reducer patterns like Redux but locally scoped. When state updates depend on previous state or involve multiple sub-values, reducers are clearer than multiple useState calls. The reducer function takes current state and a

Image upload with preview and Rails Direct Upload

Direct uploads to cloud storage bypass the Rails server, improving performance and reducing server load. I use ActiveStorage's Direct Upload feature to get presigned URLs from Rails, then upload files directly to S3 from the browser. The React compone

Laravel Inertia.js for modern SPAs

Inertia.js bridges Laravel backends with Vue, React, or Svelte frontends without building a separate API. Server-side controllers return Inertia responses containing component names and props. The frontend renders those components with reactive framew

Lazy loading routes with React.lazy and Suspense

Code splitting routes reduces initial bundle size and improves load times. React's lazy function dynamically imports components when routes are accessed. Wrapped in Suspense, lazy components show fallback UI while loading. I group related routes into

React Query for server state management

React Query eliminates boilerplate for fetching, caching, and syncing server data. Instead of managing loading/error/data states manually with useState, I define queries with useQuery that handle caching, background refetching, and stale data automati

Rails API-only app setup for React frontend

When building a React SPA, I configure Rails in API-only mode to skip view rendering, asset pipeline, and session cookies. The --api flag generates a lean Rails app focused on JSON responses. I enable CORS to allow the React dev server on localhost:51

Virtual scrolling for large lists with react-window

Rendering thousands of list items kills performance. Virtual scrolling renders only visible items plus a buffer, dramatically reducing DOM nodes. The react-window library provides FixedSizeList and VariableSizeList components that handle viewport calc

Dark mode with Tailwind and localStorage persistence

Dark mode improves usability in low-light conditions and reduces eye strain. I implement theme switching with Tailwind's dark: variant and CSS custom properties for colors. The theme preference persists in localStorage and syncs across tabs with stora

Drag and drop with dnd-kit

Drag and drop UIs feel natural for reordering lists or organizing content. The dnd-kit library provides accessible, performant drag and drop with full keyboard support. I use DndContext to wrap draggable areas, useSortable for sortable list items, and

React Hook Form + Zod resolver

Forms are where type safety and UX collide. react-hook-form keeps re-renders low, and Zod gives me a single schema I can share between frontend and backend if I want. I wire zodResolver so field-level errors show up automatically, and I keep a stable

React Suspense for data fetching

React Suspense handles async operations declaratively, showing fallback UI while data loads. With frameworks like Relay or React Query's experimental Suspense mode, components throw promises when data isn't ready, triggering the nearest Suspense bound

Performance optimization - lazy loading and code splitting

Performance optimization reduces load times and improves user experience. I use code splitting to break bundles into smaller chunks loaded on demand. React's lazy() and Suspense enable component-level code splitting. Dynamic import() loads modules asy