A Soft Introduction to React, Part 1

Samuel Newman

6th Mar 2020

a 3 minute read

So, you've heard about this thing all the cool kids are using nowadays and you're wondering how it works? Well this is the guide for you! I'm going to gently introduce React to someone who might know some web dev stuff, but who reaches for jQuery whenever they have to do something complicated.

To make this introduction as soft as possible, you can play along using codesandbox - but first, let's look at a simple thing you might want to do.

By the end of the article, we should have a counter that looks something like this:

I have been clicked 0 times

1. A Button that clicks

Say you want a button that shows an alert popup when you click it. How do you do this?

The jQuery approach

If you had the following HTML file, you'd need to first create the button, add an event listener to it, then insert it in the <div>. What a pain!

<html>
<head>
<title>jQuery Example</title>
</head>
<body>
<div id="btn-goes-here"></div>
</body>
</html>

Now comes the jQuery. Notice how we're just repeatedly doing stuff to the same variable?

$(document).ready(function() {
var button = $('<button></button>');
button.text('Click Me!');
button.on('click', function () {
alert('You clicked the button'!);
});
$('#btn-goes-here').append(button);
})

And it only gets worse, as nested elements get increasingly verbose and complicated.

Luckily, there is another way...

The React approach

import React from "react"
export const AlertButton = () => {
return (
<button onClick={() => alert("You clicked the button!")}>Click Me!</button>
)
}

Here's that exact button here:

I'm guessing you're wondering if that's HTML in the JavaScript, and the answer is kind of. This is actually JSX, a flavor of JavaScript which lets you put HTML in the middle of JavaScript, and then this is transpiled into real JavaScript that can be ran in the browser (but that's a story for another time). More importantly, there's a big difference to the approach of the two methods. React uses a declarative programming style, and traditional JavaScript/jQuery use an imperative programming style.

Declarative vs Imperative programming

To understand the difference, you need to imagine you want a painting. Using imperative painting, you would just go paint it yourself - paint the background, paint the flowers etc one by one until the painting is complete. If you were to paint it declaratively, you would declare what you want your painting to look like (blue background, 3 red flowers in a vase) and then get your friend to paint it for you.

In this metaphor, your friend is React - it handles all the painting for you (modifying values in the DOM, keeping track of changes) leaving you free to fulfil your artistic vision.

2. A Quick Breakdown

There are 3 important concepts to understand in React - components, props, and state.

Now's the time to play along! Click this link and select the React template.

Components and Nesting

React is based around components, which in JS terms are functions (or classes). For example, AlertButton is a function. The real power of this is that you can nest these functions. Here is how we could put the alert button on a page:

import React from "react"
import { AlertButton } from "./alertbutton"
export const App = () => {
return (
<div>
<h1>Alert Button Example</h1>
<AlertButton />
</div>
)
}

We could then nest App in something else, and nest that something else in another component. The possibilities are endless!

But how can components interact with each other?

Props

The answer is the next fundamental part of React - props. Props (short for properties, I assume) allows you to pass data down into child components. To demonstrate this, we're going to modify <AlertButton /> so that it takes a prop specifying the message.

export const AlertButton = ({ message }) => {
// the props are destructured here
// alternatively you could take a props parameter
// and use props.message instead
return <button onClick={() => alert(message)}>Click Me!</button>
}
export const App = () => {
return (
<div>
<h1>Alert Button Example</h1>
<AlertButton message="I'm a prop!" />
</div>
)
}

You may notice that we're passing a function to the onClick property of the button. This is because normal HTML elements take some props much like they do in real HTML - such as id. There are some important differences - they all* are now in Pascal case (i.e. onClick), and the most glaring is class is now className. Also, we're passing a function - this is important. You can pass anything to a component (arrays, objects, functions) and the component will just receive them as a prop. Passing functions is especially useful, as we will see when we come to talk about state in just a moment.

* except aria labels for some reason

One final thing is that you can also receive the children of a component - they are simply found in props.children. For example, if you wanted to make a wrapper component for adding a dollar sign:

export const Dollars = ({ children }) => {
return <p>${children}</p>
}
// <Dollars>20</Dollars> -> $20

Conditional Rendering

You remember how I said there's 3 important concepts? Well conditional rendering is pretty important too. The idea is for a component to return different things depending on its props and/or its state. This allows you to build actually useful components!

You can't really fit a whole if statement into the JSX, so the common solution is to use boolean expressions and the ternary operator. A quick recap - in JavaScript (and most programming languages) you can do something called short-circuit evaluations. These allow you to do very concise comparisons, because it checks the first value in the expression, and then only evaluates the second value if the first value is true (because if it's false, it wouldn't matter what the second one turns out to be). If the second value is a function, or even better a React component, then it will only be executed if the first value is true.

Here, I made some examples of this in 'practice':

// Okay, this component might not be 'actually useful'. Whatever.
export const DayNight = ({ isDay }) => {
// we're taking a boolean, isDay, and
// we want to return either a sun or a moon
return <p>{isDay ? "☀️" : "🌙"}</p>
}
export const Application = ({ user }) => {
return (
<div>
<NavBar>{user.isAdmin && <AdminButton />}</NavBar>
<PageContent user={user} />
</div>
)
}

State

State is by far the most important part of React. It's what makes it Reactive, so to speak.

To bring it back to the jQuery comparison for a minute, so far what we've been doing...

TO BE CONTINUED...