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 complete example code can be seen at https://codesandbox.io/s/7mk3qvk4k1