Great! Let’s now add the functionality that lets us change the count by clicking the buttons, by adding a onClickFunction prop. We pass that to the Button component, and we use an onClick event handler that intercepts automatically the clicks made on the button, and it calls the handleClick function:

const Button = ({ increment, onClickFunction }) => {
  const handleClick = () => {
    onClickFunction(increment)
  }
  return <button onClick={handleClick}>+{increment}</button>
}

When handleClick runs, it calls the onClickFunction prop, which in turn will refer back to the App component for an attached handler.

Here’s App with the new onClickFunction prop defined on the Button components:

function App() {
  let count = 0

  const incrementCount = increment => {
    //TODO
  }

  return (
    <div className="App">
      <Button increment={1} onClickFunction={incrementCount} />
      <Button increment={10} onClickFunction={incrementCount} />
      <Button increment={100} onClickFunction={incrementCount} />
      <Button increment={1000} onClickFunction={incrementCount} />
      <span>{count}</span>
    </div>
  )
}

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.

This function must increment the local count. How can we do so? We can use hooks (read an intro to hooks on https://flaviocopes.com/react-hooks/).

We import useState from React, and we call:

const [count, setCount] = useState(0)

when we need to use define our count. Notice how I removed the count let variable now. We substituted it with a React-managed state.

In the incrementCount function, we call setCount(), incrementing the count value by the increment we are passed.

Why we didn’t just update the count value, why do we need to call setCount()? Because React depends on this convention to manage the rendering (and re-rendering) of components. Instead of watching all variables and spend time and resource trying to “spy” on values and do something when they change, it tell us to just use the set* function, and let it handle the rest.

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.

Here’s the full code:

import React, { useState } from 'react'
import ReactDOM from 'react-dom'
import Button from './components/Button'

import './styles.css'

function App() {
  const [count, setCount] = useState(0)

  const incrementCount = increment => {
    setCount(count + increment)
  }

  return (
    <div className="App">
      <Button increment={1} onClickFunction={incrementCount} />
      <Button increment={10} onClickFunction={incrementCount} />
      <Button increment={100} onClickFunction={incrementCount} />
      <Button increment={1000} onClickFunction={incrementCount} />
      <span>{count}</span>
    </div>
  )
}

const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

The react counter

The complete example code can be seen at https://codesandbox.io/s/7mk3qvk4k1


Go to the challenges