useClampedCounter Hook

MediumReact Hooks20 min5 tests

Build a custom useClampedCounter(min, max, initial) hook that exposes a count clamped to a [min, max] range plus inc/dec updaters, then wire it to a small counter UI whose buttons disable at the bounds.

Custom hooks are how you package stateful logic so it can be reused and tested in isolation. In this exercise you'll implement useClampedCounter(min, max, initial).

The hook returns an object { count, inc, dec }:

  • count — the current value, always kept within the inclusive range [min, max].
  • inc() — increases count by 1, but never above max.
  • dec() — decreases count by 1, but never below min.

The starting value should also be clamped: if initial is outside the range, count begins at the nearest bound.

Wire the hook into the App component. Render:

  • A heading.
  • A live region (role="status") that always shows the current count.
  • A Decrease button that calls dec() and is disabled when count === min.
  • An Increase button that calls inc() and is disabled when count === max.

Use the hook with min = 0, max = 5, initial = 0. Because initial is 0 and min is 0, the Decrease button starts disabled.

The clamping logic must live inside the hook (using useState and useCallback/plain handlers) — the component should only consume { count, inc, dec } and render UI.

Requirements

  • Implement useClampedCounter(min, max, initial) inside App.tsx returning { count, inc, dec }
  • count must always stay within the inclusive [min, max] range, including the initial value
  • inc() increments by 1 capped at max; dec() decrements by 1 floored at min
  • Render a role="status" element that always displays the current count
  • Render a 'Decrease' button (calls dec) that is disabled when count === min
  • Render an 'Increase' button (calls inc) that is disabled when count === max
  • Use the hook with min=0, max=5, initial=0
Hints (3)
  1. Write a small clamp helper: Math.min(max, Math.max(min, value)). Use it both when seeding initial state and inside inc/dec.
  2. Seed state lazily with the clamped initial value: useState(() => clamp(initial)). Inside inc/dec use the functional updater form, e.g. setCount(c => clamp(c + 1)).
  3. Drive the buttons' disabled prop directly from count: Decrease is disabled when count === min, Increase when count === max. Read the value from role="status".

Topics

  • React
  • React Hooks

Asked at

BookMyShow · Paytm · Freshworks · Dream11 · Uber · Urban Company

Join Us
blur