typescript
83 lines · 1 tab
Maya Patel
Jan 2026
1 tab
import { useReducer } from 'react'
interface FormState {
values: Record<string, any>
errors: Record<string, string>
touched: Record<string, boolean>
isSubmitting: boolean
}
type FormAction =
| { type: 'CHANGE_FIELD'; field: string; value: any }
| { type: 'TOUCH_FIELD'; field: string }
| { type: 'SET_ERRORS'; errors: Record<string, string> }
| { type: 'SET_SUBMITTING'; isSubmitting: boolean }
| { type: 'RESET' }
function formReducer(state: FormState, action: FormAction): FormState {
switch (action.type) {
case 'CHANGE_FIELD':
return {
...state,
values: {
...state.values,
[action.field]: action.value,
},
errors: {
...state.errors,
[action.field]: '', // Clear error on change
},
}
case 'TOUCH_FIELD':
return {
...state,
touched: {
...state.touched,
[action.field]: true,
},
}
case 'SET_ERRORS':
return {
...state,
errors: action.errors,
}
case 'SET_SUBMITTING':
return {
...state,
isSubmitting: action.isSubmitting,
}
case 'RESET':
return initialState
default:
return state
}
}
const initialState: FormState = {
values: {},
errors: {},
touched: {},
isSubmitting: false,
}
export function useFormReducer() {
const [state, dispatch] = useReducer(formReducer, initialState)
return {
state,
changeField: (field: string, value: any) =>
dispatch({ type: 'CHANGE_FIELD', field, value }),
touchField: (field: string) =>
dispatch({ type: 'TOUCH_FIELD', field }),
setErrors: (errors: Record<string, string>) =>
dispatch({ type: 'SET_ERRORS', errors }),
setSubmitting: (isSubmitting: boolean) =>
dispatch({ type: 'SET_SUBMITTING', isSubmitting }),
reset: () => dispatch({ type: 'RESET' }),
}
}
1 file · typescript
Explain with highlit
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 an action, returning new state. Actions are objects with type and optional payload. This pattern centralizes state logic, making it easier to test and reason about. I use useReducer for complex forms, wizards, or mini state machines. Combined with Context, it provides Redux-like architecture without external dependencies. TypeScript discriminated unions ensure type-safe action handling.
Related snips
typescript
import axios, { AxiosError } from 'axios'
import { v4 as uuidv4 } from 'uuid'
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000/api/v1',
timeout: 15000,
Axios API client with interceptors
react
axios
api
by Maya Patel
1 tab
typescript
import { create } from 'zustand'
import { persist } from 'zustand/middleware'
interface FilterState {
search: string
category: string | null
Zustand for lightweight state management
react
zustand
state-management
by Maya Patel
2 tabs
swift
import SwiftUI
struct ContentView: View {
@State private var username = ""
@State private var isLoggedIn = false
@StateObject private var viewModel = LoginViewModel()
SwiftUI declarative UI with state management
swift
swiftui
ios
by Sofia Martinez
2 tabs
typescript
import React from "react";
type FallbackProps = {
error: Error;
reset: () => void;
};
React Error Boundary + error reporting hook
react
frontend
error-boundary
by codesnips
3 tabs
javascript
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
openAnalyzer: true,
});
/** @type {import('next').NextConfig} */
Next.js bundle analyzer for targeted performance work
nextjs
performance
tooling
by codesnips
4 tabs
typescript
import { Navigate, useLocation } from 'react-router-dom'
import { useAuth } from '@/contexts/AuthContext'
interface ProtectedRouteProps {
children: React.ReactNode
}
React Router with protected routes
react
react-router
routing
by Maya Patel
2 tabs
Share this code
Here's the card — post it anywhere.