Sign in

Learn React.js by Building Hacker News (Part 3) — JSX and adding CSS To Your App

In this article, you will start building out your React application and get into the most important concept in React, Javascript XML (JSX).

JSX is easy to pick up if you are familiar with HTML and JavaScript.

This article was originally published on my blog, I would love it if you could give me a visit and subscribe to my newsletter while you are there for regular updates of my new posts!

If you ended up here without reading the previous sections, you can find all the previous parts below. I would recommend reading this series in order.

Hacker News Clone Series:

Part 1: What is React?
Part 2: Create-React-App Internals
Part 3: JSX and adding CSS To Your React App
Part 4: Function vs Class Based Components

You can find all of the source code for the series at my Github. The source code can be found here.

Clone this branch, open up a terminal in the folder, run npm start, and let's get right into it.

What is JSX?

JSX is the syntax used by React to embed HTML into a JavaScript file. It also allows you to nest JavaScript into those HTML components as well. The JSX code is compiled into HTML and Javascript using Babel.

Babel is a transpiler. A transpiler converts the source code into an equivalent source code in another language. A great reference for transpilers can be found here at Javascript Transpilers by Peleke Sengstacke.

Let’s take a look at App.js.

function App(){
return (
<div className="App">
<h1>Hello World</h1>
</div>
)
}

Here we can see some interesting syntax that looks like a combination of Javascript and HTML.

The return statement can be thought of as a wrapper for everything that shows up on the page in that component. We see Hello World in our local environment because we render it via the return statement.

Although the syntax look’s similar to HTML, there are some rules to consider when working with JSX.

Multiple HTML Tags

The first consideration to make is when we want to return multiple items in the return statement. Nested elements must be wrapped in at least one parent container.

In the App.js file, we have nested the <h1> tag within a parent <div>.

Let’s remove, the parent <div> container and see what happens.

function App(){
return (
<h1>Hello World</h1>
)
}

Did nothing happen? That’s expected, it will only throw an error if there are multiple HTML elements.

Let’s add a couple more elements.

function App(){
return (
<h1>Hello World</h1>
<p>I am Color Coder</p>
<p> I like to write things </p>
)
}

You should see the following error now.

Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment.

No big deal, let’s fix this error by wrapping the elements within a <div> container.

function App() {
return (
<div>
<h1>Hello World</h1>
<p>I am Color Coder</p>
<p> I like to write things </p>
</div>
);
}

We should be back in business now.

Now let’s starting building out our barebones navigation component of Hacker News.

We can layout the menu items using <a> tags and use a nested image for the logo. You can find the logo within the source code. I've left the href as a placeholder for now until we start building out the other pages.

Aside: React requires you to pass in a value for alt text aatribute in <img> tags.

function App() {
return (
<div>
<a href="#"><img src="/assets/logo.gif" alt="hn logo"/></a>
<a href="#">Hacker News</a>
<a href="#">new</a> |
<a href="#">threads</a> |
<a href="#">comments</a> |
<a href="#">ask</a> |
<a href="#">show</a> |
<a href="#">jobs</a> |
<a href="#">submit</a>
<a href="#">login</a>
</div>
);
}

Might not look great yet but it’s a start.

Defining JSX Attributes

JSX Attributes are optional parameters that can be passed into the JSX tags. In React, these attributes are referred to are Properties (props). This includes everything you would recognize from classes to event handlers. You can find the full list of all the available props at the React Dom Elements documentation.

Let’s start styling this to resemble the navigation bar. Styling in React can be done in two ways.

  1. Inline Styling
  2. Importing from external CSS files.

Inline CSS Styling

To style CSS inline we need to pass the style prop into a JSX element. Let's add the background color to the navigation bar.

First add a style prop to the parent <div> container. A prop is enclosed in curly braces {}. The style prop takes a JavaScript object containing the styles we would like to add. You can read more about styles in React here.

One thing to note is that the property names from CSS when using JSX vary a little bit. JSX uses camel-case notation to identify the property. So instead of background-color: color, we would remove the hyphen and convert it to camel-case. backgroundColor: 'color'. Also, note that the property value must be a string as React expects a Javascript object.

function App() {
return (
<div style={{backgroundColor: '#ff6600'}}>
<a href="#"><img src="/assets/logo.gif" alt="hn logo"/></a>
<a href="#">Hacker News</a>
<a href="#">new</a> |
<a href="#">threads</a> |
<a href="#">comments</a> |
<a href="#">ask</a> |
<a href="#">show</a> |
<a href="#">jobs</a> |
<a href="#">submit</a>
<a href="#">login</a>
</div>
);
}

You should end up with this,

Let’s add some more styles to make this more like the actual website.

function App() {
return (
<div style={{
backgroundColor: "#ff6600",
display: "flex",
flexDirection: "row",
color: "black",
padding: "2px",
}}
>
<a href="#"><img src="/assets/logo.gif" alt="hn logo"/></a>
<a href="#">Hacker News</a>
<a href="#">new</a> |
<a href="#">threads</a> |
<a href="#">comments</a> |
<a href="#">ask</a> |
<a href="#">show</a> |
<a href="#">jobs</a> |
<a href="#">submit</a>
<a href="#">login</a>
</div>
);
}

Hold on, this is starting to get messy. Imagine if we needed to style each of those links, that would be a lot of information written inline.

Let’s optimize and refactor the code by storing style as a variable.

function App() {
return (
const navStyles = {
backgroundColor: "#ff6600",
display: "flex",
flexDirection: "row",
color: "black",
padding: "2px",
};


<div style={navStyles}
>
<a href="#"><img src="/assets/logo.gif" alt="hn logo"/></a>
<a href="#">Hacker News</a>
<a href="#">new</a> |
<a href="#">threads</a> |
<a href="#">comments</a> |
<a href="#">ask</a> |
<a href="#">show</a> |
<a href="#">jobs</a> |
<a href="#">submit</a>
<a href="#">login</a>
</div>
);
}

This is better but once again if we had complex applications with more components we would need to create multiple variables and styles. There has to be a better way.

The better way: external Style Sheets.

Similar to when developing a vanilla website using HTML/CSS we can define external CSS files and then import them into our application.

Create React App provides us with an index.css and an App.css file. The index.css file is the global stylesheet that is applied to our index.js file. Here we can store the styles that we want to carry throughout our application.

Remove all the existing content and add the following code into your index.css file.

/** Utilities **/
.bold {
font-weight: bold;
}
:root{
--orange: #ff6600;
}
/** Globals **/
html {
box-sizing: border-box;
}
body {
font-family: Verdana, Geneva, sans-serif;
color: black;
}
.container {
display: flex;
width: 80%;
margin: 0 auto;
}
a {
text-decoration: none;
color: #000;
}

The App.css file is CSS file defined to be used within App.js. This introduces modularity and decouples your styles into multiple files. This makes your code organized and easy to work on. Let’s delete the App.css file and under the src directory, create another directory called styles.We will store all our styles within this folder.

React will likely throw an error but don’t worry about it as it is because App.js references the App.css file which we deleted. We will remove that soon.

Then create a file called Nav.css in the styles directory.

Add the following code into the Nav.css file.

/** Navigation Styling **/
.navigation {
display: flex;
flex-direction: row;
align-items: center;
background-color: var(--orange);
color: black;
padding: 2px;
width: 100%;
}
.navigation a {
padding: 0px 5px;
}
.hn-logo {
border: 1px solid white;
margin-top: 2px;
}
.title {
margin-right: 5px;
}
.navigation .login {
margin-left:auto;
}

Now we will need to inject this CSS into our application.

Open up App.js and change the import statement reference from the deleted App.css file to the following.

import "./styles/Nav.css";

Now we can use the className prop to attach CSS classes to the tag. This is equivalent to adding the class attribute to an HTML tag.

Here is the full App.js file,

import "./styles/Nav.css";function App() {    return (
<div className="container">
<div className="navigation">
<a href="#">
<img
className="hn-logo"
src="/assets/logo.gif"
alt="hn logo"
/>
</a>
<a href="#" className={"bold title"}>
Hacker News
</a>
<a href="#">new</a> |<a href="#">threads</a> |
<a href="#">comments</a> |<a href="#">ask</a> |
<a href="#">show</a> |<a href="#">jobs</a> |
<a href="#">submit</a>
<a href="#" className="login">
login
</a>
</div>
</div>
);
}
export default App;

Final Result

You did it, you styled and built out your own Hacker News navigation!

What’s next?

Now that you have a grasp of how JSX and styling work in React. We will start exploring further concepts in JSX such as JS Expressions and Comments. We will start refactoring code by introducing the technical aspects of React Functional and Class-Based Components.

If you liked this tutorial and are enjoying the series. Make sure you subscribe to my newsletter to keep up with the latest posts and updates. The next tutorial will be delivered right to your inbox.

See you in the next one!

If you would like to suggest topics for me to cover or would like to chat feel free to email me. You can find more posts like this at www.colorcoder.dev. Thanks for reading! :)

Posts, tutorials, snippets and all the antics I’m up to. www.colorcoder.dev

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store