Skip to content

shadcn.io is an independent project built on shadcn/ui

Docs

Free

useCounter for React

A number with increment, decrement, reset and setCount already wired. For React, when a quantity, a page index or a score moves one step at a time.

useCounter keeps a number, plus increment, decrement, reset, and setCount.

Use it for a quantity stepper, a score, or a page index. When the value is only on or off, use useBoolean. In React increment and decrement keep the same identity, so a child button can take them without a new function each render.

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

useCounter anatomy: useCounter(), decrement, count, increment, reset

Usage

import { useCounter } from "@/hooks/use-counter";
const { count, increment, decrement, reset, setCount } = useCounter();

With no argument the count starts at 0, and reset returns to that same initial value.

FAQ

When should I use useCounter instead of useState?

Use it when you want increment, decrement, and reset without writing them. increment and decrement are memoized with an empty dependency list, so they are safe to pass to a child. useState is enough when you only set the number in one place. setCount is still there for any other update.

How do I step by more than one?

Call setCount with a function. increment and decrement always change the number by one, and they take no argument. setCount is the raw state setter, so setCount with a function receives the current number and can add five, multiply, or jump to a value. There is no step option on the hook.

Can I set a minimum or a maximum?

Not in the hook. Nothing clamps the number, so decrement from 0 goes negative and increment never stops. Do the bound inside setCount, for example by taking the smaller of your max and the next number. reset goes back to the initial value even if that value sits outside a bound you apply elsewhere.

What does reset go back to?

The initial value from the call, or 0 when that argument was missing. reset reads the latest initial value, because it is in the dependency list. Changing the argument does not change count by itself. It changes only what the next reset writes. A missing argument and an explicit 0 behave the same way.

Can the count go negative?

Yes. decrement subtracts one with no floor, and increment adds one with no ceiling. The hook never checks the sign. If you need to stay at zero or above, do that in setCount instead of calling decrement. The displayed number is whatever state currently holds.

Is useCounter safe to render on the server?

Yes. It uses useState and useCallback only. It never reads window or document, so the server and the client both start from the same initial number. That number is the argument you passed, or 0 when you left it out. A bad argument is not checked at runtime.

API Reference

Parameters

ParameterType
initialValue?number

The count it starts with, and resets to. 0 when left out.

Returns

ValueType
countnumber

The current count.

decrement() => void

Subtracts 1. Stable across renders.

Type
() => void
increment() => void

Adds 1. Stable across renders.

Type
() => void
reset() => void

Puts the count back to initialValue (or 0).

Type
() => void
setCountReact.Dispatch<React.SetStateAction<number>>

Sets the count directly, or from the current one: useState's setter.

Type
React.Dispatch<React.SetStateAction<number>>