useNumberTicker
Animating numerical counters via React useState triggers up to 120 full component re-renders per second, degrading dashboard UI performance. useNumberTicker animates numbers smoothly on the shared FrameConductor by mutating DOM textContent directly with zero React re-renders.
The useNumberTicker hook eases numerical values to their targets by writing directly to the attached DOM node's textContent property inside the FrameConductor render lane.
The hook automatically sets font-variant-numeric: tabular-nums on the target element, ensuring numbers remain aligned without layout jitter as digit widths change.
Built on top of standard Intl.NumberFormat, the hook formats currencies, percentages, and locale-specific decimal separators seamlessly. When data values update mid-animation, the transition retargets smoothly without restarting from zero.
◆Zero-Re-Render Interactive Dashboard Counters
Quick start
Attach the returned ref to a span element. The hook handles interpolation, formatting, and DOM updates automatically.
Tabular numeric font styling is applied automatically to prevent layout width wobble.
Intl Formatting Recipes & Precision
Configure localized currencies, signed percentage metrics, and custom unit suffixes.
| Format Type | Configuration Example | Sample Output |
|---|---|---|
| Currency (USD) | { format: { style: "currency", currency: "USD", maximumFractionDigits: 0 } } | $428,500 |
| Signed Percentage | { suffix: "%", format: { signDisplay: "exceptZero", minimumFractionDigits: 2 } } | +3.42% |
| Latency / Units | { suffix: " ms", format: { maximumFractionDigits: 1 } } | 14.8 ms |
| European Locale | { locale: "de-DE", format: { maximumFractionDigits: 0 } } | 24.800 |
API Reference
Syntax
Interpolates a numeric value toward target numbers on the conductor render lane without React state re-renders.
Parameters
| Parameters.field | Type | Default | Description |
|---|---|---|---|
| value | number | (none) | The target numerical value to animate towards. |
| options.speed | number | 6 | Damping catch-up speed per second. Higher values reach target faster. |
| options.format | Intl.NumberFormatOptions | undefined | Standard Intl configuration for currencies, percentages, and decimal places. |
| options.locale | string | browser | Locale string (e.g. 'en-US', 'de-DE') used for number localization. |
| options.prefix | string | "" | Static string prepended to the formatted output (e.g. '+', '~'). |
| options.suffix | string | "" | Static string appended to the formatted output (e.g. '%', ' ms'). |
Return Value
Ref attached to the HTML text element.
Properties & State
| Properties.field | Type | Description |
|---|---|---|
| ref | RefObject<T | null> | DOM ref bound to the text element whose textContent is mutated. |
Conductor Unsubscription Lifecycle
The hook subscribes to the FrameConductor render lane upon mount and unsubscribes cleanly on unmount.
Lifecycle & Invariant Guarantees
- →Zero React re-renders: Animation frames mutate textContent directly on the DOM node, preserving React fiber tree stability.
- →Tabular digits stability: Applies font-variant-numeric: tabular-nums to prevent character width jitter during transitions.
- →Frame-rate independence: Calculates exponential damping based on live delta-time, behaving identically at 60Hz, 120Hz, or 240Hz.
- →Dynamic retargeting: Smoothly shifts target destinations mid-flight without snapping or restarting from initial values.
◆Production Examples
Battle-tested production patterns ready to copy directly into your codebase.
Smoothly ease prices when users toggle between monthly and annual plans.
When NOT to use this
Rules & Gotchas
- →Separate application state from display presentation: Store the authoritative numeric value in application state; use the hook exclusively for visual transition smoothing.
- →Feed meaningful discrete state changes: Trigger updates on user interactions, toggle selections, or polled intervals rather than noisy continuous streams.
- →Avoid continuous screen reader announcements: Direct textContent updates provide standard accessibility; reserve aria-live alerts for discrete status updates.
- →Animate only visible viewport elements: On large data tables or dashboards, instantiate tickers only for currently visible rows.