Overview
TheuseWeather hook is a sophisticated custom hook that manages weather data fetching with a multi-step async workflow. It demonstrates advanced patterns including sequential API calls, localStorage integration, automatic data loading on mount, and comprehensive state management.
Purpose
This hook showcases advanced React patterns for:- Managing complex async workflows with multiple API calls
- Implementing localStorage for state persistence
- Auto-loading data on component mount with
useEffect - Using
useCallbackfor stable function references - Handling loading, success, and error states
- Coordinating geocoding and weather API calls
API Reference
Hook Signature
Parameters
This hook takes no parameters.Return Value
Current state of the weather data fetching. Can be one of:
'idle': No search performed yet'loading': Currently fetching data'success': Data fetched successfully'error': An error occurred during fetching
Weather data object when available. Contains:
cityName: string - Name of the citycountry: string - Country codecurrent: CurrentWeatherData - Current weather informationtemperature_2m: number - Temperature in Celsiuswind_speed_10m: number - Wind speed in km/hweather_code: number - WMO weather code
daily: DailyForecastData - 7-day forecasttime: string[] - Array of datestemperature_2m_max: number[] - Max temperaturestemperature_2m_min: number[] - Min temperaturesweather_code: number[] - Weather codes
Error message if status is ‘error’, otherwise null
Async function to search weather for a given city. Performs geocoding first, then fetches weather data, and saves the city to localStorage.
The last searched city name retrieved from localStorage (empty string if none)
Implementation Details
Key Implementation Details
Lazy Initialization of savedCity
Lazy Initialization of savedCity
The hook uses lazy initialization to read from localStorage only once:This prevents reading localStorage on every render.
Unified State Object
Unified State Object
Instead of separate state variables, the hook uses a single state object:This ensures all related values update atomically, preventing intermediate states.
useCallback for Stable Reference
useCallback for Stable Reference
The This provides a stable function reference that won’t change between renders, crucial for the
search function is wrapped in useCallback with an empty dependency array:useEffect dependency.Sequential API Calls
Sequential API Calls
The hook performs two sequential API calls:The second call depends on the first, demonstrating async dependency management.
Auto-Loading on Mount
Auto-Loading on Mount
The hook automatically loads weather for the last searched city:This provides a seamless user experience by restoring the previous state.
Comprehensive Error Handling
Comprehensive Error Handling
Errors are caught and properly typed:This ensures type safety while handling both Error objects and other thrown values.
Usage Examples
Basic Usage
- App Component
- SearchBar Component
- CurrentWeather Component
- WeatherForecast Component
App.tsx
Advanced Usage with Custom Hook Composition
useWeatherWithHistory.ts
Design Patterns
This hook demonstrates several advanced React patterns:
1. Unified State Management
Instead of managing loading, data, and error separately:2. Lazy State Initialization
Reading localStorage only once during initialization:3. Stable Function References with useCallback
Preventing infinite loops in useEffect:4. Sequential Async Operations
Chaining dependent API calls:5. Type-Safe Error Handling
State Flow Diagram
Performance Considerations
Preventing Unnecessary Renders
Preventing Unnecessary Renders
Using
useCallback with empty deps ensures the search function doesn’t change, preventing child components from re-rendering unnecessarily.Lazy Initialization
Lazy Initialization
The lazy initialization pattern for
savedCity ensures localStorage is only read once, not on every render.Atomic State Updates
Atomic State Updates
The unified state object ensures all related values update together, preventing multiple renders from separate setState calls.
Auto-Loading Trade-off
Auto-Loading Trade-off
The auto-load feature on mount improves UX but makes an API call immediately. Consider adding a delay or user preference to control this behavior.
Best Practices Demonstrated
This hook exemplifies several React best practices:
- TypeScript for Type Safety: All types are properly defined
- Unified State: Related state values are kept together
- Stable References: Functions are memoized with useCallback
- Lazy Initialization: Expensive operations only run once
- Proper Error Handling: Try-catch with type-safe error messages
- Side Effect Management: useEffect for auto-loading
- localStorage Integration: Persistent user preferences
- Input Validation: Trimming and checking for empty strings
Potential Enhancements
- Debouncing: Add debouncing to prevent excessive API calls
- Request Cancellation: Cancel in-flight requests on new search
- Cache with Expiration: Cache results with TTL to reduce API calls
- Retry Logic: Implement automatic retry on failure
- Optimistic Updates: Show loading state with previous data
- Request Deduplication: Prevent duplicate concurrent requests
Related Hooks
useCounter
Learn basic custom hook patterns
useGifs
Explore caching patterns with useRef