Build a simple counter with React
By Flavio Copes
Build a simple counter in React: render buttons that increment the count by 1, 10, 100, or 1000, wiring each click through state and an onClickFunction prop.
In this short tutorial we’ll build a very simple example of a counter in React: a number on screen, and four buttons that increment it by 1, 10, 100 or 1000. It’s a small app, but it touches props, events and state, the core of how React works.
Let’s use Codepen for this. We start by forking the React template pen.
In Codepen we don’t need to import React and ReactDOM as they are already added in the scope.
Rendering the UI
We show the count in a div, and we add a few buttons to increment this count:
const Button = ({ increment }) => {
return <button>+{increment}</button>
}
const App = () => {
let count = 0
return (
<div>
<Button increment={1} />
<Button increment={10} />
<Button increment={100} />
<Button increment={1000} />
<span>{count}</span>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('app'))
Notice count is a plain variable here. That’s a problem we’ll hit in a minute: React does not watch plain variables. Changing count would not update the screen, because nothing tells React to re-render.
Handling clicks
The buttons live in the Button component, but the count lives in App. A child component can’t change its parent’s data directly. The parent passes down a function instead, and the child calls it.
Let’s add the functionality that lets us change the count by clicking the buttons, by adding a onClickFunction prop:
const Button = ({ increment, onClickFunction }) => {
const handleClick = () => {
onClickFunction(increment)
}
return <button onClick={handleClick}>+{increment}</button>
}
const App = () => {
let count = 0
const incrementCount = increment => {
//TODO
}
return (
<div>
<Button increment={1} onClickFunction={incrementCount} />
<Button increment={10} onClickFunction={incrementCount} />
<Button increment={100} onClickFunction={incrementCount} />
<Button increment={1000} onClickFunction={incrementCount} />
<span>{count}</span>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('app'))
Here, every Button element has 2 props: increment and onClickFunction. We create 4 different buttons, with 4 increment values: 1, 10 100, 1000.
When the button in the Button component is clicked, the incrementCount function is called.
Adding state
This function must increment the local count. How can we do so? We can use hooks:
const { useState } = React
const Button = ({ increment, onClickFunction }) => {
const handleClick = () => {
onClickFunction(increment)
}
return <button onClick={handleClick}>+{increment}</button>
}
const App = () => {
const [count, setCount] = useState(0)
const incrementCount = increment => {
setCount(count + increment)
}
return (
<div>
<Button increment={1} onClickFunction={incrementCount} />
<Button increment={10} onClickFunction={incrementCount} />
<Button increment={100} onClickFunction={incrementCount} />
<Button increment={1000} onClickFunction={incrementCount} />
<span>{count}</span>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('app'))
useState() initializes the count variable at 0 and provides us the setCount() method to update its value.
We use both in the incrementCount() method implementation, which calls setCount() updating the value to the existing value of count, plus the increment passed by each Button component.
Calling setCount() is what makes React re-render App, so the new count shows up on screen. That’s the difference from the plain variable we started with.
One thing to know: if you ever call setCount() more than once inside the same event handler, each call sees the same old count value. The fix is the functional form, setCount(current => current + increment), which always receives the latest value. With one call per click, like here, both work fine.

The complete example code can be seen at https://codepen.io/flaviocopes/pen/QzEQPR