knowledge-kitchen

React.js - Intro

For people who want to make something appear in a browser, but don’t want to write HTML & CSS code.

  1. Overview
  2. A Word About HTML & CSS
  3. React Setup From Scratch
  4. React Setup From Git
  5. Components
  6. Props
  7. State
  8. Side-Effects
  9. Fetching Data From Servers and APIs
  10. Linking From One Screen To Another
  11. Conclusions

Overview

Concept

React.js is a tool for auto-generating HTML, CSS, and browser-based Javascript for web app client interfaces.

Choice of approach

A front-end generator

React.js programs themselves are not web apps - they comprise neither the front nor the back end.

Components are standardized, reusable, and shareable

The key value proposition of React.js is that it produces standardized reusable code.

A Word About HTML & CSS

Concept

Any web browser understands the three core front-end web technologies:

Javascript

In addition to controlling the interactive behaviors of web pages running in web browsers, Javascript has found new life in other environments:

HTML in three slides (slide 1)

For any given web page, HTML code indicates the type of content to show as well as each piece of content’s purpose, or semantic meaning.

<article>
  <h1>Puppies For Sale</h1>
  <img src="images/lonely_puppy.jpg" />
  <p>
    Buy now while supplies last!
    <a href="puppies.html">Learn more</a>
  </p>
</article>

Try it

HTML in three slides (slide 2)

Many web sites see the same basic content structures repeated across multiple pages, or repeated within a single page. Try it!

<section>
  <!-- the first article -->
  <article>
    <h1>Puppies For Sale</h1>
    <img src="images/lonely_puppy.jpg" />
    <p>
      Buy now while supplies last!
      <a href="puppies.html">Learn more</a>
    </p>
  </article>
  <!-- the second article... notice its structural similarity to the first -->
  <article>
    <h1>Kittens For Sale</h1>
    <img src="images/sad_kitten.jpg" />
    <p>
      Get 'em while they're hot!
      <a href="kittens.html">Learn more</a>
    </p>
  </article>
</section>

HTML in three slides (slide 3)

Actually, we’re more-or-less finished explaining HTML in 2 slides.

What you just learned is how to code for content that will be displayed in the body of a web page - the part of an HTML document that represents the visible content.

CSS in three slides (slide 1)

For any given web page, CSS code indicates the style to use for the content indicated by the HTML.

article {
  border: 10px dotted pink;
  font-family: georgia;
  font-weight: bold;
  padding: 20px;
}

Try it!

CSS in three slides (slide 2)

Let’s say you had four paragraphs, and wanted to style only two of them the same. Mark them with a class attribute in the HTML. If you want to uniquely style only one, mark it with an id attribute:

<p>Lorem ipsum dolor sit amet.</p>
<p class="my_favorite_paragraphs">Ipsum dolor sit amet lorem.</p>
<p id="a_really_special_paragraph">Dolor sit amet lorem ipsum.</p>
<p class="my_favorite_paragraphs">Ipsum dolor sit amet lorem.</p>

And select only the paragraphs that match these attributes in the CSS:

p.my_favorite_paragraphs {
  box-shadow: 5px 5px 10px; /* a drop shadow */
}
p#a_really_special_paragraph {
  font-size: 24px; /* relatively big */
}

Try it!

CSS in three slides (slide 3)

That’s almost it. But there is one very important part of CSS code that we will not address here is how you place elements onto the web page in the location where you want them to go.

There are a variety of ways… the latest greatest is to CSS Flexbox - see a simple example - flexbox is how layouts should be done with React.

Auto-generating HTML & CSS

Now that you have a mastery of HTML & CSS (!), you will use React.js to autogenerate some of it for you.

Try it!

React Setup From Scratch

Install Node.js

Since React.js is built to run in it, a developer must first install Node.js

Create project directories

If creating a React app from scratch, first create project directory where everything related to your app - front-end, back-end, and React code - will reside.

mkdir my-app
cd my-app

Since you’ll eventually need it, take the opportunity to make a sub-directory for the back-end code.

mkdir back-end

Create a starter React app

In the project directory, create a React starter project - this will create the basic directory structure, install any necessary dependencies, set up configuration files, and include simple React app starter code that is immediately runnable.

npx create-react-app front-end

Remove git

create-react-app automatically installs git version control tracking into the directory it creates for the React code.

We will want to use git to track our entire project, not just the front-end generator code. So we need to remove git from the front-end directory.

cd front-end
rm -rf .git # remove the hidden directory where git keeps its files
rm .gitignore # remove the hidden git settings file

Try it out

To preview the app in a non-optimal state, try running it.

Verify that your working directory is front-end and start up the React preview script.

npm start

This will run the script named start automatically included in the new app’s configuration file - it launches a preview of the app.

Try generating HTML, CSS, and Javascript files

The previous command previews the app. To generate the proper HTML, CSS, and browser-based Javascript files that will ultimately comprise the app front-end, run the following:

npm run build

This will run the script named build automatically included in the package.json configuration file.

Poke around the file system

You should familiarize with the React app files and directories.

Set up git for the entire project

Navigate to the main project directory where you will initialize git version control tracking.

cd .. # go up a level to the parent directory of both front-end and back-end
git init # install git

Instruct git to ignore files that are not yours

In the main project directory (the parent directory of front-end and back-end), create a file named .gitignore that will inform git of files not to track.

React Setup From Git

Clone a git repository

If cloning an existing React app, or a fork of an app, stored in a Git remote repository, use git clone, as with any git repository.

git clone https://github.com/some-username/my-app.git

This will create a new directory named my-app (or whatever name the repository had) where all the project files are stored.

Navigate into this directory and to any sub-directory where the standard npm configuration file named package.json is, and run npm install in order to install any necessary dependencies for this project.

npm install

Follow along

The React.js code examples in this slide deck are available on GitHub - the code is already set up and ready to run.

Components

Concept

A React component is a modular, reusable user interface element.

Component classes

Defining a component with a Javascript class is the most common way, because it was the original way React designed them.

Here is a component class named Hello that represents a paragraph of text.

class Hello extends Component {
  render() {
    return <p>Hello world!</p>
  }
}

Component functions

Defining a component as a function is now the preferred way and simplifies the code a bit.

function Hello() {
  return <p>Hello world!</p>
}

The same function can be written this way, if you remember your Javascript fat arrow syntax:

const Hello = () => <p>Hello world!</p>

Try it!

JSX

This embedding of HTML-like code into the middle of Javascript code is not ordinary Javacript - it is React’s JSX.

const Foo = () => {
  return <p>Doesn't this look a lot like HTML code in your Javascript?!</p>
}

Multi-element components

Components can contain multiple user interface elements.

const Hello = () => {
  return (
    <div>
      <h1>React Component</h1>
      <p>Hello world!</p>
    </div>
  )
}

Try it!

Components are not exactly HTML

While JSX components look almost identical to HTML code, and there is a React component for every HTML element by the same name, they are not HTML and have some slightly different behavior.

For example, to add a class to an HTML element, you use the class attribute.

<p class="my_favorite_paragraphs">Ipsum dolor sit amet lorem.</p>

To have React render that same HTML, you would have to use the className attribute in JSX (unlike HTML, all attributes in JSX have lowerCamelCase names):

<p className="my_favorite_paragraphs">Ipsum dolor sit amet lorem.</p>

Supposedly, this is because class is a reserved word in Javascript, and JSX code is transpiled to Javascript behind-the-scenes. We find that justification lacking.

Components are not exactly HTML (continued)

Attributes in HTML typically have quotes around their values.

<p class="my_favorite_paragraphs">Ipsum dolor sit amet lorem.</p>

If injecting a variable or other expression as the value for an attribute in JSX, you cannot surround the variable in quotes, but it does have to be in curly brackets.

<p className="{someVariable}">Ipsum dolor sit amet lorem.</p>

Read more

Components are not exactly HTML (continued again)

HTML allows CSS styles to be written inline in an HTML element in a special style attribute:

<p style="color: blue; background-color: pink;">Ipsum dolor sit amet lorem.</p>

JSX requires a Javascript object to be passed as the style attribute value.

const pStyle = {
    color: 'blue',
    backgroundColor: 'pink'; // notice the camelCase style property names - this is Javascript, not CSS!
}

And injected into the JSX without quotes around it.

<p style="{pStyle}">Ipsum dolor sit amet lorem.</p>

Read more

Components are not exactly HTML (one last time)

Interactive behaviors can be attached to elements in HTML with case-insensitive attributes, such as onclick, onmouseover, onmouseout, and more, and usually including code for a simple function call that is automatically executed when the interactive event occurs.

<p onclick="someFunction()">click me</p>

In React, equivalent behaviors are written with lowerCamelCase attributes and must to refer to a function definition that is automatically called when the interactive event occurs.

<p onClick="{someFunction}">click me</p>

Styling components

import "./Article.css"

Styling components (continued)

Given the following JSX:

<article className="intro">
  <h1 className="intro-heading">React Component</h1>
  <p className="intro-paragraph">Hello world!</p>
</article>

React CSS should select components by their className attribute, not by the type of HTML element they are rendered as, since this may vary.

.intro {
  border: 1px solid red;
}
.intro-heading {
  font-family: georgia;
}
/* etc */

Try it!

Props

Accepting arguments

Props are arguments passed to a component that can influence its content or behavior.

This custom Article component accepts a props object as its argument and injects some of the values therein into the JSX content:

const Article = (props) => {
  return (
    <article>
      <h1>{props.heading}</h1>
      <p>{props.paragraph</p>
    </article>
  )
}

Accepting arguments

Using Javascript’s object destructuring, this function could be rewritten:

const Article = ( { heading, paragraph }) => {
  return (
    <article>
      <h1>{heading}</h1>
      <p>{paragraph</p>
    </article>
  )
}

Try it!

Passing props

This custom Section component includes two Article components nested within it

const Section = () => {
  return (
    <section>
      <article
        heading="Puppies for Sale"
        paragraph="Get 'em while they last!'"
      />
      <article heading="Free Kittens" paragraph="Anytime, anywhere!'" />
    </section>
  )
}

Try it!

Functions as arguments

Javascript, of course, has higher-order functions, and can accept function definitions as arguments to a function call.

For example, this component will call any function passed to it as an argument named action whenever the user clicks the paragraph:

const Card = props => {
  return (
    <div>
      <p onClick={props.action}>Click me!</p>
    </div>
  )
}

Note the lowerCamelCase spelling of the onClick attribute, like all JSX attributes.

Functions as arguments (continued)

We could easily pass the definition of the function to run as one of the props properties in the component that includes the Card component we defined:

<Card action={ () => { alert("See what I mean? Javascript is fun!") } } />
<Card action={ () => { fetch('https://my.api.mockaroo.com/animals.json?key=d9ddfc40') } } />

Try it!

Summary

Props are a jargon word for arguments passed to a function that represents a component.

State

Concept

In React, state variables help keep track of the internal state of the component.

// create a state variable with default value 0
// store a reference to the variable, and a reference to a function that can be called to change its value
const [count, setCount] = useState(0)

This code creates a state variable named count.

Binding

State variables can be injected into any JSX component, just like any other Javascript expression.

<p>You clicked the button {count} times</p>

Binding (continued)

Unlike other expressions, any changes to the value stored in a state variable will be immediately updated in the component.

const MyComponent = () => {
  const [count, setCount] = useState(0)
  return (
    <div>
      <p>You clicked the button {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  )
}

Anytime the button is clicked, the state variable is incremented, and the paragraph automatically shows the updated number. Try it

State management

There are a variety of ways to share state between one component and another.

Side-Effects

Concept

Every time React renders a component onto the web page, such as when the page first loads or after a change in state, it is possible to run side-effects.

The useEffect function

You can define a function within the component that indicates any side-effects you desire, and pass it to React’s useEffect function.

useEffect(() => {
  // write whatever code you want run every time the component renders.
  console.log("the component has rendered or re-rendered!")
})

Watching for state variable changes

You may not want to run the code within useEffect’s callback function every time the component renders.

An optional second argument accepts an array. If any variable in the array’s value has changed since last time the component was rendered, the useEffect callback will be executed.

useEffect(() => {
  // write whatever code you want run every time the component renders.
  console.log("the component has rendered or re-rendered!")
}, [count])

It is usually the practice to place specific state variables you want to watch into this array.

Cleaning up after side-effect code

Some side-effects will need to be undone if a component is removed from the page.

useEffect(() => {
  console.log("the component has rendered or re-rendered!")
  return () =>
    console.log("the component has been completely removed from the page!")
}, [count])

A practical example

The following useEffect callback sets up an eventListener - a function to be called automatically whenever the browser window width changes.

useEffect(() => {
  const handleResize = () => setWidth(window.innerWidth)
  window.addEventListener("resize", handleResize)
  return () => window.removeEventListener("resize", handleResize)
}, [])

Running a side-effect only once

Note the blank array as second argument to useEffect in the previous example.

Fetching Data From Servers & APIs

Concept

It is often the case that front-end Javascript code fetches data from a back-end web server or API.

How does front-end code request, receive, and process data from the back-end?

Data structures

Data retrieved from a server can come in any structure. However, it’s not uncommon to receive an array of JSON objects.

;[
  {
    id: 1,
    title: "Mule deer",
    country: "Brazil",
    price: "$27.77",
    description:
      "Curabitur in libero ut massa volutpat convallis. Morbi odio odio, elementum eu, interdum eu, tincidunt in, leo. Maecenas pulvinar lobortis est.",
  },
  {
    id: 2,
    title: "Monkey, bleeding heart",
    country: "Malaysia",
    price: "$13.30",
    description:
      "Integer ac leo. Pellentesque ultrices mattis odio. Donec vitae nisi.",
  },
  // etc
]

Axios

Axios is a popular 3rd-party module that makes it easy to fetch data from a server.

// fetch some mock data about animals for sale
const response = await axios(
  "https://my.api.mockaroo.com/animals.json?key=d9ddfc40"
)
// extract the data from the server response
const data = response.data

In the case of React, we can also add that data a state variable we have previously initialized.

setData(response.data)

Iterating through an array of objects

Assuming the variable, data, contains an array of objects, we can iterate through it the standard way.

data.map(item => (
    console.log( item );
))

Outputting JSX from an array

In the case of React, where the data is stored in a state variable, we can place the loop within a JSX component.

<div>
  <h1>Animals For Sale</h1>
  <section className="animals">
    {data.map(item => (
      <Animal key={item.id} details={item} />
    ))}
  </section>
</div>

Outputting JSX from an array

The Animal component can now use the object’s information by accessing it in the props parameter.

const Animal = props => {
  return (
    <article className="animal">
      <h2>{props.details.title}</h2>
      <address>{props.details.country}</address>
      <strong>{props.details.price}</strong>
      <p>{props.details.description}</p>
    </article>
  )
}

Try it!

Linking From One Screen To Another

The ‘a’ component

As with its HTML a element equivalent, the JSX a component provides the simplest a way to link from one screen to another.

<a href="/puppies/2">Click me!</a>

As with all JSX attributes, Javascript variables or expressions can be injected as the link’s href attribute value if desired:

<a href={`/puppies/${puppyId}`}>Click me!</a>

Note that while using an a component to create a link will work, it is not the most efficient way to do so. It will cause the browser to reload an entirely new page, which is not necessary in most cases.

The react-router-dom module

react-router-dom is a 3rd-party module that provides streamlined navigation solutions, including:

To include it in a project, use npm install to save it as a dependency in the package.json configuration file:

npm install --save react-router-dom

Then import into your code:

import { BrowserRouter as Router, Routes, Route } from "react-router-dom" // as n example, we are here importing just those components useful for setting up front-end routes

The react-router-dom module (continued)

For example, the following sets up a few mutually-exclusive front-end routes, indicating the components that should be loaded at each URL.

<Router>
  <Header />

  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/about" element={<About />} />
    <Route path="/animals" element={<AnimalsList />} />
    <Route path="/animals/:id" element={<Animal />} />
  </Routes>

  <Footer />
</Router>

Setting up these route paths is typically done in the top-level component, often called App.js.

The react-router-dom module (continued again)

The react-router-dom module also includes a Link component that can be used to link from one component to another. This is the prefered way to create links from one screen to another when using React.

First, import the Link component:

import { Link } from "react-router-dom"

Then use it in a JSX component to link to another component:

<Link to="/animals">See all animals</Link>

The react-burger-menu module

react-burger-menu is a 3rd-party module that provides streamlined hamburger menu functionality’:

To include it in a project, use npm install to save it as a dependency in the package.json configuration file:

npm install --save react-burger-menu

Then import into your code:

import { slide as Menu } from "react-burger-menu"

Conclusions

Now you have some understanding of using React to generate HTML, CSS, and Javascript for a client-side web pages.