How to Build an Extensible Counter List in React Building a list of counters is a classic React exercise, but making that list extensible requires smart state management and clean architecture. An extensible system allows you to add features—like custom increments, labels, or reset triggers—without rewriting your core logic.
Here is how to build a highly scalable, extensible counter list in React using modern functional components and custom hooks. 1. The Core Architecture
To make a list extensible, we must separate state management from UI rendering.
We will use a central array of objects in the parent component’s state. Each counter object will have a unique identity and its own independent value.
ID: Keeps track of items accurately during additions and deletions. Value: Stores the current count.
This component focuses purely on presentation. It receives its value and action handlers via props, making it highly reusable.
// CounterItem.jsx import React from ‘react’; export default function CounterItem({ id, value, label, onIncrement, onDecrement, onRemove }) { return (
{label || Counter ${id}}{value}
); } Use code with caution. Step 2: Manage List State in the Parent Component
The parent component manages the array of counters. We use immutable state updates to add, remove, and modify individual counters based on their unique IDs.
); } Use code with caution. 3. Why This Design is Extensible
Because the state shapes are decoupled, expanding this application requires minimal effort. Here are three ways you can easily extend this system: Extension A: Dynamic Steps
Want some counters to jump by +5 instead of +1? Simply add a step property to your state object: javascript
// In state { id: 3, value: 0, label: ‘Bulk Item’, step: 5 } // In handler onIncrement={(id) => updateValue(id, counter.step || 1)} Use code with caution. Extension B: Global Statistics
Because the data lives in a central parent array, you can easily derive global metrics using standard JavaScript array methods without adding new state:
Total Items Logged: {totalCount} Across {activeCounters} Counters
; Use code with caution. Extension C: Persistent Storage
You can hook this state directly into localStorage using a useEffect hook to ensure users do not lose their data on page refresh: javascript
useEffect(() => { localStorage.setItem(‘my-counters’, JSON.stringify(counters)); }, [counters]); Use code with caution. 4. Summary of Best Practices
Keep state flat: Avoid deeply nested structures so updates remain performant and readable.
Use unique keys: Never use the array index as a React key when items can be reordered or deleted. Use Date.now() or a UUID generator.
Favor derived state: Calculate global sums and averages on the fly during render rather than syncing multiple state variables. If you want to take this project further, let me know:
Should we integrate a useReducer hook for complex state tracking? Do you need help adding styling / animations to the list?
Tell me what feature you want to build next and I can provide the code!
Leave a Reply