Refactoring Habit Streak Logic Into a Single React Hook
How habit-streak calculation—timezones, night shifts, custom reset hours—can be centralized into a single reusable React hook, with notes on testability and UX pitfalls.
Habit-streak tracking looks trivial until you hit timezones, midnight logging, and the question of when a user's 'day' actually ends. Rather than scattering this logic across components, the source consolidates it into a single useStreak hook, making the calculation both reusable and independently testable. The resetHour parameter is the key detail—it lets night-shift users log a midnight workout without their streak breaking simply because the app assumes everyone's day resets at 12am.
Wrapping this logic as a hook rather than a plain utility function matters because of composability: useStreak can be layered with other hooks like useNotificationSchedule or useMilestone without re-threading the same recalculation logic through multiple components, keeping the codebase easier to maintain as it grows.
The piece also flags a behavioral caveat beyond the code: streaks are a motivational device, not a health metric, and a single missed day can trigger all-or-nothing thinking. For health-adjacent products, it suggests showing 'longest streak' alongside 'current streak' so a broken streak doesn't erase a user's sense of progress—a small UI decision with real psychological impact.