It's not too late to learn react so, here is my journey. I will try to post everyday about the progress I made. I tried to learn react last year but was not able to finish it and now I'm again a noob.
So, this is my 2nd shot in learning react. Haven't touched the basics of it but instead I will try to learn it by building some projects.
The first project I build is Roll a Dice. This is a very simple one and gave a good idea of how the file structure works and everything to the base level in react. Also, I'm using next.js to build this small web application. I just want to be comfortable with both of these things at the same time that's why.
What I learn
- React.js and Next.js file structure
- Running and creating a react application
- Some jsx
- HTML and CSS in react
- useState Hook
- and other basic stuff
Now, let's build.
Roll a Dice Web App in React.js and Next.js
Create repo
This is not necessary but it's an good idea to keep everything in Github repo for various needs. But mine is to have some commits everyday on my profile and learn every system that I need to accomplish in real world job.
I just then cloned that repo in my system. Opened the terminal, cd into project directory.
Creating the project
Since, I'm using Next.js so, the command to create the project will be:
npx create-next-app@latest .
.
in the end so, it won't create another directory in the project project folder and take base directory name as it is.
You can then select your preferred configuration like JS or TS. I'm using JS, for tailwind say no. Since it's a very small project we don't need that.
After completion of the installation. Run the command to test if it's working.
npm run dev
Visit localhost:3000, you should see the vercel/next.js landing page.
If upto this point if everything is working fine. Congratulations, we have now learned how to create a react project using next.js.
Clean up the files
The next step is to clean some files and remove the unwanted code from our project.
You can read about the project structure here, I won't talk about this here.
Remove everything except the page.js and layout.js from the src/app directory.
layout.js
The default code should look like this:
import { Inter } from "next/font/google";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
We're going to remove some of it and keep and add what we need for this project.
Remove the second import
of CSS or just rename it to style.css
. We can keep the fonts. Next we have export metadata. We're going to change it instead of removing to
export const metadata = {
title: "Roll a Dice",
description: "A simple roll a dice web app!",
};
Next keep the remaining Root function. The end code of the file should look like this:
import { Inter } from "next/font/google";
import "./style.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata = {
title: "Roll a Dice",
description: "A simple roll a dice web app!",
};
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
Next, create a style.css
file under the same directory src/app
, because we need one style file and we imported it on the top of layout.js file.
page.js
In this file, let's remove everything and write from the beginning. Let's first have a function to render our homepage with a simple heading text.
export default function Home() {
return (
<main className="page">
<h1>Roll a Dice</h1>
</main>
);
}
In this code, we have a simple react function which returns a simple h1
in our application.
Next, we need the dice image and a button to roll it. We want the image to randomly change to another one upon clicking that button.
Images
Before that let's collect some images for the dice. I have already downloaded them from the web. So, you can copy these 6 images from the repo. Store them in the public folder. Make sure it is present in the root directory, same level as src
directory.
- roll-dice
-- src/app
-- public/all-your-images.png
Make sure the dice images are named like this:
dice-1.png
dice-2.png
...
dice-6.png
You can name it whatever you want just please adjust it accordingly in the code.
page.js
Now, let's create an image and the button, which we talked earlier. For the image we need to import the Image
component from next.js since we're using next.js.
import Image from "next/image";
export default function Home() {
return (
<main className="page">
<div className="img-side">
<Image src="/dice-1.png" width="400" height="400" />
</div>
<div className={"text-side"}>
<h1>Roll a Dice</h1>
<p>
Roll a Dice is a user-friendly web app that simulates dice rolls.
Perfect for games or decision-making, it offers quick, random results
with a single click.
</p>
<button>Roll the dice</button>
</div>
</main>
);
}
Now, our web app looks like this:
style.css
Let's add some styling to it. I won't talk about this much. Here's the CSS:
body {
background-color: #f0f0f0;
padding: 10px;
}
body,
* {
margin: 0;
}
.page {
max-width: 850px;
padding: 20px;
margin: 0 auto;
background-color: #fff;
border-radius: 28px;
display: grid;
gap: 20px;
align-items: center;
}
.img-side img {
width: 350px;
height: auto;
max-width: 100%;
}
.text-side h1 {
margin-bottom: 10px;
}
.text-side button {
padding: 12px 28px;
line-height: 1;
border: solid 2px #222;
background-color: #222;
color: #fff;
font-size: 17px;
letter-spacing: 0.5px;
border-radius: 18px;
margin-top: 30px;
cursor: pointer;
transition: cubic-bezier(0.6, -0.28, 0.735, 0.045) 0.2s all;
}
.text-side button:hover {
opacity: 0.9;
}
@media (min-width: 850px) {
.page {
grid-template-columns: 1fr 1fr;
}
}
Now, the web app looks like this:
Adding the functionality
Again in page.js
, we're going to import a useState which an react hook using import { useState } from "react";
. First let's do the destructuring and initialize the variable with 1.
import Image from "next/image";
import { useState } from "react";
export default function Home() {
const [num, setNum] = useState(1);
Then we're going to create random number generator function inside our Home
function, which is going to return a number from 1 to 6.
import Image from "next/image";
import { useState } from "react";
export default function Home() {
const [num, setNum] = useState(1);
const randomNumberInRange = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
....rest of the code
Now, we need a function that fires our randomNumberInRange
function.
import Image from "next/image";
import { useState } from "react";
export default function Home() {
const [num, setNum] = useState(1);
const randomNumberInRange = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
const handleClick = () => {
setNum(randomNumberInRange(1, 6));
};
return (
....rest of the code
Now, we have to assign the handleClick
function to the button. So, it works on click. Let's do that:
<button onClick={handleClick}>Roll the dice</button>
We're mostly done with our web app. We just need to make some adjustments in the Image
tag so, it can use the random num
from our function. To do that, modify the Image
src
to <Image src={"/dice-" + num + ".png"} width="400" height="400" />
.
Now, the page.js
code should look like this:
"use client";
import Image from "next/image";
import { useState } from "react";
export default function Home() {
const [num, setNum] = useState(1);
const randomNumberInRange = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
const handleClick = () => {
setNum(randomNumberInRange(1, 6));
};
return (
<main className="page">
<div className="img-side">
<Image src={"/dice-" + num + ".png"} width="400" height="400" />
</div>
<div className={"text-side"}>
<h1>Roll a Dice</h1>
<p>
Roll a Dice is a user-friendly web app that simulates dice rolls.
Perfect for games or decision-making, it offers quick, random results
with a single click.
</p>
<button onClick={handleClick}>Roll the dice</button>
</div>
</main>
);
}
Now, if you click on the button. The image should start changing like rolling a dice.
And that's it for this web app, atleast for now.
If you have any suggestions or feedback, then please share! The repo is here
Top comments (0)