How To Make A Counter Application With React Usestate Hook
Learn how to make a simple counter app with React useState()
In recent times, React.js has become very popular to the extent that almost every frontend developer wants to learn how to use it. Unless they are fanatically [or perhaps passionately] attracted to any other frontend library or framework actually. In React version 16.8 release, hooks were added and since then, working with React has become easier and fun, compared to when class-based components were the de facto method to build a robust web app with the library. In this article, I will guide you through the basics of React useState() hook by making a simple counter application.
To get up and running with React, we have to set up our development environment by installing React and will be using the CLI (Command Line Interface) tool create-react-app, which is very popular in the React ecosystem. You install create-react-app by running
npm-create-react-app myapp
In our case, myapp is the name of our app. After installation, change the directory to the myapp folder by running cd myapp
I’m using myapp here but you can call your app anything you want. Run npm start
to start the development server which is always available at port 3000, i.e. localhost:3000. When the server starts running on port 3000, you see a spinner as shown in the image below
Do some cleanups by removing the test files and everything in the App.js file.
To start bringing the counter app to life, import the useState hook from React by typing “import React { useState } from ‘react’” and the app.css file by typing “import ‘./app.css’”. Declare a function called App and return a div with Counter App in an h1 tag as shown in the snippet below:
import React, { useState } from "react";
import "./App.css";
const App = () => {
return (
<div>
<h1>Counter App</h1>
</div>
);
};
export default App;
You can also use a fragment instead of div, as I did below
import React, { useState } from "react";
import "./App.css";
const App = () => {
return (
<>
<h1>Counter App</h1>
</>
);
};
export default App;
We must export our App component using ES6 modules, that's why you can see export default App
in the last line of the snippet.
Now, you should have Counter App shown in an h1 tag in the browser.
To start building the counter app, we have to declare a state with our useState hook. This is normally done by declaring two variables, the state and another to update the state, setState. This is done by using array destructuring and initializing the state to 0.
import React, { useState } from "react";
import "./App.css";
const App = () => {
// Declare state and initialize it to 0
const [count, setCount] = useState(0);
return (
<div>
<div className="title">
<h1>Counter App</h1>
</div>
</div>
);
};
export default App;
Seems I just cheated by placing my Counter App h1 in a div with the class name of title. Don't worry, you'll see why later.
In React, there are always multiple ways of doing things, so you can also declare a variable above the App component, initialize it to 0, and pass it into the useState hook. With respect to the counter app, I have declared a count and setCount variable.
import React, { useState } from "react";
import "./App.css";
const initialState = 0;
const App = () => {
// Declare state and initialize it to 0
const [count, setCount] = useState(initialState);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increase</button>
<span>{count}</span>
<button onClick={() => setCount(count - 1)}>Decrease</button>
</div>
);
};
export default App;
In the div [or fragment if you choose to] we returned, we have to add two buttons, one for increasing the counter and the other for decreasing it, then wrap our count variable inside a span tag. You can use the p tag if you want, but I don’t want to get an extra line, so I’m going with span, which does not create an extra line because it is an inline element.
import React, { useState } from "react";
import "./App.css";
const App = () => {
// Declare state and initialize it to 0
const [count, setCount] = useState(0);
return (
<div>
<div className="title">
<h1>Counter App</h1>
</div>
<button>Decrease</button>
<span>{count}</span>
<button>Increase</button>
</div>
);
};
export default App;
To start increasing and decreasing the counter, we need to set up the functions to do that. This is done by passing an onClick function into the two buttons. We can execute the functions inline as shown below:
import React, { useState } from "react";
import "./App.css";
const initialState = 0;
const App = () => {
// Declare state and initialize it to 0
const [count, setCount] = useState(initialState);
return (
<div>
<button onClick={() => setCount(count - 1)}>Decrease</button>
<span>{count}</span>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
};
export default App;
Right before the return statement, React allows us to write pure JavaScript, so, we can pass the identifier into the onClicks then write the functions before the return statement. I called the two functions handleIncrease and handleDecrease. This is cleaner and easier to read than executing the functions inline. And like I said earlier, there are always multiple ways of doing things in React. I want to show you the ways, so you can choose which works for you best.
import React, { useState } from "react";
import "./App.css";
const App = () => {
// Declare state and initialize it to 0
const [count, setCount] = useState(0);
const handleIncrease = () => {
setCount(count + 1);
};
const handleDecrease = () => {
setCount(count - 1);
};
return (
<div>
<div className="title">
<h1>Counter App</h1>
</div>
<button onClick={handleDecrease}>Decrease</button>
<span>{count}</span>
<button onClick={handleIncrease}>Increase</button>
</div>
);
};
export default App;
Now, things should be working correctly, so head over to the browser and start increasing and decreasing Yaay 🙌
To make our little app a little more beautiful, let’s add the styles in the snippet below:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
button {
padding: 10px;
border: 2px solid #3498db;
border-radius: 4px;
background-color: #2ecc71;
color: #fff;
cursor: pointer;
font-size: 20px;
transition: 0.5s ease;
}
button:hover {
border: 2px solid #2ecc71;
background-color: #3498db;
}
span {
padding: 10px;
font-size: 20px;
}
.title {
margin-bottom: 16px;
}
h1 {
color: #2ecc71;
}
After everything, this is what I have in my browser:
Thank you so much for reading. If you find any errors, please let me know in the comment section. If you want to see an article on React useEffect() hook from me, comment below. If you would like any other article on React too, let me know and I would start working on it right away.
Connect with me via my portfolio or Twitter , where I spend most of my time engaging in web development related issues.
This article was initially posted on dev.to