I am Software Engineer, who has always been a little intimidated by front end development, but hopefully that's about to change. I am more of a backend-er. I usually just reach the point with front end where my work looks professional enough, then I start running in the opposite direction. So this lockdown we're gonna work on our relationship and make amends, front end!
Why Document?
To keep myself motivated and lock myself in a routine to stick to, I decided to document my learning journey and the problems I face. That way I get to learn twice, once through absorbing all the concepts and the other, when I am writing about them. As a bonus, I will also get a great reference for myself to go back to, when I fall into the same problems I once fell into, like the forgetful fish I know I am.
So let's get our React feet wet!
What Do I Need?
Learning by doing is the best process for me to achieve any progress, so the first question I asked myself was: What do I need to start coding other than the obvious essentials as a text editor or an IDE and a browser?
After a little exploration here and there I set up the React Developer Tools extension in my browser for debugging and I already had the ESLint extension installed in my editor, so I thought that should be enough for now.
I also found out that I have 2 paths, when it comes to adding React to a project:
- The easy way for simpler projects: include some scripts in an HTML file and we'd be good to go
- The more convenient way for more complex projects: create-react-app
As a true beginner, who has not been worn out by apathy, I decided to walk down both roads. Instead of just printing out "Hello, World!" I thought maybe for change's sake I'll make things a tad more interesting and build another thing just as simple.
Build What?
Since in lockdown, time has taken its role as an illusion seriously and most of us agree that every day has simply lost its first name and turned into just day, my hello world app would just pop up what day it is today, whenever time loses its purpose.
We will try to create a unique brand for each day to make it stand out among its colleagues.
Check out what we're about to build: https://ranaemad.github.io/whatdaytoday/
JSX
I quickly went through React.createElement()
, but once I found JSX I knew I have reached my destination.
When it comes to JSX, I think all we need to know for now, is that HTML married Javascript and had a stubborn child who refuses to use class and replaces it with className, among a couple of other modifications, but he's nice enough to let us use Javascript expressions, so we like him.
The Easy Way
Time to get our hands dirty! I started by creating a whatdaytoday.html file in my root folder, added some basic HTML boilerplate in it, added a div with id app to render our content in and linked a main.css file in it for later customization.
whatdaytoday.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>What Day Today?</title>
<link rel="stylesheet" href="main.css" />
</head>
<body>
<div id="app"></div>
</body>
</html>
To use React all we have to do is include a couple of script tags before closing our body.
<script
src="<https://unpkg.com/react@16/umd/react.development.js>"
crossorigin
></script>
<script
src="<https://unpkg.com/react-dom@16/umd/react-dom.development.js>"
crossorigin
></script>
Nice, but that would work if we're using the createElement() method, what if we want to run JSX? To do that we will need the help of Babel to compile our code for us, so we will include 1 more script tag.
<script src="<https://unpkg.com/babel-standalone@6/babel.min.js>"></script>
Great! We are all set! Now let's add our React code in a separate react.js file.
Let's start by adding a div with an image and dummy text and render them into our app div.
react.js
const App = (
<div className="day">
<div className="heading">Thursday</div>
<img src="thursday.svg alt="thursday" />
</div>
);
ReactDOM.render(App, document.getElementById("app"));
I have included SVG images that represent each day in the root folder and everything looks fine, then why is it not working? Hmmm...
I kept refreshing and googling for 5 minutes before I realized, I am not running a server (which Babel needs for compiling external scripts) and I am just opening the path to the HTML file in the browser.
Cool cool cool, running php -S localhost:8080
solved the problem for me, but any other server would have worked just fine.
Now that we're sure everything works, let's get the day dynamically from today's date and replace our dummy text and image with a custom one.
I'll initialize all the days data in a week array and go from there.
react.js
let week = [
{
day: "Sunday",
img: "sunday.svg",
},
{
day: "Monday",
img: "monday.svg",
},
{
day: "Tuesday",
img: "tuesday.svg",
},
{
day: "Wednesday",
img: "wednesday.svg",
},
{
day: "Thursday",
img: "thursday.svg",
},
{
day: "Friday",
img: "friday.svg",
},
{
day: "Saturday",
img: "saturday.svg",
},
];
const day = new Date().getDay();
const today = week[day];
const App = (
<div className={"day " + today.day.toLowerCase()}>
<div className="heading">{today.day}</div>
<img src={today.img} alt={today.day} />
</div>
);
ReactDOM.render(App, document.getElementById("app"));
Good, now we can throw some css in our main.css file to make each day stand out.
main.css
@import url("<https://fonts.googleapis.com/css2?family=Great+Vibes&display=swap>");
.day {
height: 100vh;
font-family: "Great Vibes", cursive;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.heading {
font-size: 4.5rem;
margin-bottom: 0;
font-weight: bold;
}
.day img {
width: 50vw;
}
.wednesday .heading {
color: #f9a727;
text-shadow: 2px 2px #3f3d55;
}
.saturday .heading {
color: #e50914;
text-shadow: 2px 2px #00bfa6;
}
.thursday .heading {
color: #2f2f41;
text-shadow: 2px 2px #00b0ff;
}
.friday .heading {
color: #d83e75;
text-shadow: 2px 2px #2f2f41;
}
.sunday .heading {
color: #ff6584;
text-shadow: 2px 2px #3f3d55;
}
.monday .heading {
color: #0e01bf;
text-shadow: 2px 2px #ffb8b8;
}
.tuesday .heading {
color: #36799a;
text-shadow: 2px 2px #ffb8b8;
}
@media screen and (max-width: 600px) {
:root {
font-size: 10px;
}
}
@media screen and (max-width: 300px) {
:root {
font-size: 5px;
}
}
Annnnd it is up and running YAY!
You can find the code for this section HERE
The More Convenient Way
Let's transfer the code from the previous section to fit into create-react-app! To use create-react-app we have to have node installed and luckily, I already do. I just ran npx create-react-app .
in my root folder and went from there.
To start the app I simply ran npm start
and it was automatically up and running on port 3000 outputting the React logo on screen.
I gave the folder structure a look and decided that's for future Rana to worry about and for now I am just going to find the app starting point and replace what's already there with my code and see if it works. (SPOILER ALERT: it did!)
I went straight to the App.js file, imported all the days SVG images placed in the src folder, the same way the React logo was imported. After that, I had to make a tiny modification in the week array to make the img point to a variable instead of text. The changes are instantly reflected in the browser and I don't have to refresh. I already love create-react-app. <3
src/App.js
import React from "react";
import sunday from "./sunday.svg";
import monday from "./monday.svg";
import tuesday from "./tuesday.svg";
import wednesday from "./wednesday.svg";
import thursday from "./thursday.svg";
import friday from "./friday.svg";
import saturday from "./saturday.svg";
import "./App.css";
let week = [
{
day: "Sunday",
img: sunday,
},
{
day: "Monday",
img: monday,
},
{
day: "Tuesday",
img: tuesday,
},
{
day: "Wednesday",
img: wednesday,
},
{
day: "Thursday",
img: thursday,
},
{
day: "Friday",
img: friday,
},
{
day: "Saturday",
img: saturday,
},
];
After that, I replaced the already existing JSX code with mine and also replaced the css in App.css annnd we did it! Our work here is done!
You can find the code for this section HERE
By this mini victory I shall end my first baby step towards React greatness, until we meet in another one.
Any feedback or advice is always welcome. Reach out to me here, on Twitter, there and everywhere!