useNumber is a hook for managing numeric state with convenient methods: setValue, increment, decrement, reset. It returns a hybrid structure that supports both tuple and object destructuring.
function useNumber(initialValue?: number): UseNumberReturn;-
Parameters
initialValue?: number— starting value; defaults to0.
-
Returns:
UseNumberReturn— a hybrid structure with fields/positions:value: number— current value;setValue(newValue: number): void— replace the value with an explicit number;increment(step?: number): void— increase bystep(defaults to1);decrement(step?: number): void— decrease bystep(defaults to1);reset(): void— reset back to the initialinitialValue.- tuple access:
[value, setValue, increment, decrement, reset].
import { useNumber } from '@webeach/react-hooks/useNumber';
export function Counter() {
const [count, setCount, inc, dec, reset] = useNumber(5);
return (
<div>
<output>{count}</output>
<button onClick={() => inc()}>+1</button>
<button onClick={() => dec()}>-1</button>
<button onClick={() => setCount(42)}>set 42</button>
<button onClick={() => reset()}>reset</button>
</div>
);
}import { useNumber } from '@webeach/react-hooks/useNumber';
export function Stepper() {
const counter = useNumber(0);
return (
<div>
<output>{counter.value}</output>
<button onClick={() => counter.increment(10)}>+10</button>
<button onClick={() => counter.decrement(5)}>-5</button>
<button onClick={() => counter.reset()}>reset</button>
</div>
);
}import { useNumber } from '@webeach/react-hooks/useNumber';
export function NumericInput() {
const state = useNumber(0);
return (
<label>
<input
type="number"
value={state.value}
onChange={(event) => state.setValue(Number(event.target.value))}
/>
<button onClick={() => state.increment()}>+1</button>
<button onClick={() => state.decrement()}>-1</button>
</label>
);
}-
Hybrid structure
- Both forms are available: tuple
[value, setValue, increment, decrement, reset]and object{ value, setValue, increment, decrement, reset }.
- Both forms are available: tuple
-
Stable actions
- Methods
setValue,increment,decrement,resetare stable between renders; safe to include in effect/callback dependency arrays.
- Methods
-
Default step and sign
- If
stepis not provided,1is used. A negative step flips direction (e.g.,increment(-2)decreases by 2).
- If
-
Reset to the initial value
reset()returns to the latestinitialValueprovided to the hook on the current render.
-
No range checks
- The hook does not enforce bounds. For
min/max, add your own wrapper (clamping) aroundsetValue/increment/decrement.
- The hook does not enforce bounds. For
- Counters, quantities (qty), pagination, offset indices.
- Simple numeric settings (steps, limits) when you need
+,−, and reset actions. - When a stable API with explicit actions is preferable to ad‑hoc calculations in each handler.
- If you need complex transition logic/validation — use
useReduceror a custom hook. - If you need to memoize a derived value rather than store state — use
useMemo. - If the value must support controlled/uncontrolled modes (
value/defaultValue) — useuseControlled.
-
Expecting a functional setter
setValuetakes a number, not a function like(prev) => next. For relative changes, useincrement/decrement.
-
Resetting to “zero” instead of the initial
reset()returns toinitialValue, which isn’t necessarily0.
-
Passing the handler directly
- Avoid
onClick={setValue}— the event object would be passed as a number and result inNaN. Use a wrapper:onClick={() => setValue(0)}.
- Avoid
-
String values from
<input>event.target.valueis a string. Convert it:Number(event.target.value)orparseFloat(...).
Exported types
-
UseNumberReturn- Hybrid return type combining object and tuple forms.
-
UseNumberReturnObject- Object form:
{ value: number; setValue: (value: number) => void; increment: (step?: number) => void; decrement: (step?: number) => void; reset: () => void }.
- Object form:
-
UseNumberReturnTuple- Tuple form:
[value: number, setValue: (value: number) => void, increment: (step?: number) => void, decrement: (step?: number) => void, reset: () => void].
- Tuple form: