Learning React With Create-React-App (Part 1)

Last Updated: 11/17/2017

bzzt bzzt I’m a computer bzzt bzzt

Current Versions

create-react-app: v1.4.3

react: v16.1.1

react-scripts: v1.0.17

Introduction

If you’ve been reading up on web technologies lately, then odds are you’ve heard of/read about/learned React.js already. One of the major complaints that was always repeated about React was how difficult it was to get started building an application. There are, of course, ways around this. First, you could just use a CDN link to React inside of your webpage and instantly have the ability to use React, but without some other niceties that come with a proper React development environment. Learning Webpack/Brunch/Browserify/etc, however, is often a non-starter for people who want to start working with React in a more modern way (using JSX and ES6, for example, which is totally worth the effort!).

So, what’s a web developer to do when faced with the cliff of Webpack/Babel/Brunch/NPM/Node/React? Simple, just use create-react-app!

Author’s Note: Any commands you need to run in a terminal will be in the following format (don’t include the $ in any of these!):

$ run-some-command
Output from the command will be here!
$ run-some-other-command
This is more output. It might look
like the above, but might be on different lines!

And any code blocks will look like this:

// Create our initial helloWorld function
const helloWorld = () => {
console.log("Hello world!");
};
// And then call our new function
helloWorld();

Updates To create-react-app

Since the last time I updated this article the create-react-app world has significantly improved, so there are a few things I want to mention really quick just in case you had followed/read this article in the past and are curious what’s new!

  1. yarn is now default in create-react-app. yarn is basically a far more predictable and faster version of npm and is absolutely a welcome addition!
  2. The index.html/favicon.ico file now live in public instead of the root directory!
  3. create-react-app now ships with jest by default as its testing harness/framework! This means new react apps will treat testing like a first-class citizen!

Intended Audience

This tutorial is largely aimed at people who want to start exploring React and are at least comfortable with having nodejs/npm installed on their machines and people who have at least some background in Javascript and CSS. If you already know React, you can skip pretty much this entire tutorial (but if you’re curious about create-react-app, read the “Exploring Our First App” section!).

If you need to install nodejs/npm on your machine, please visit: https://nodejs.org/.

If you want to get started with Javascript, I recommend https://www.codecademy.com/learn/javascript

I’ll be covering some of the changes in ES2015 as we go along and explaining what they are/what they do/etc.

What Is Create-React-App

create-react-app is, quite simply, an answer to the common complaints of Javascript Fatigue or the sheer difficulty of getting started in a common React environment, which usually involves configuring a combination of things such as webpack, babel, and react. The complaints are best summed up in this tweet:

To their credit, the React team has done an amazing job and React is, in my mind, the simplest Javascript framework out there to jump into and get started with, but removing barriers to entry is something that every single developer out there should be striving for whenever possible.

Thus enters create-react-app. Now, getting started with React in a development environment that mirrors what you’d see working with React in a professional setting is very simple! And don’t worry, because the team has also helpfully included an “eject” command on create-react-app that pulls your new React application out of their base configuration and allows you to further tweak their base config into whatever toolset and modifications you’d prefer!

Installing Create-React-App

Assuming we already have node/npm installed, we can jump right into installing create-react-app! We’ll want to run the following command in our terminal:

$ npm install -g create-react-app

Alternatively, if you’re big on using Yarn, you can use Yarn to install create-react-app globally instead!

$ yarn global add create-react-app

We’ll verify that our install of create-react-app is working with:

$ create-react-app --version
create-react-app version: 1.4.3

Great! Let’s get started by making our favorite Hello World example!

Creating Our First React App

First, start off by moving into wherever you want to develop your application. In that directory, we’re going to create an app called “hello-world”:

$ create-react-app hello-world
(...tons of output)
Success! Created hello-world at /Users/brandon/Documents/dev/create-react-app/hello-world
Inside that directory, you can run several commands:
yarn start
Starts the development server.
yarn run build
Bundles the app into static files for production.
yarn test
Starts the test runner.
yarn run eject
Removes this tool and copies build dependencies, configuration files
and scripts into the app directory. If you do this, you can’t go back!
We suggest that you begin by typing:
cd hello-world
yarn start
Happy hacking!

The instructions at the end are really the important part. There are four default commands bundled into create-react-app: start, build, test, and eject. Also, notice that create-react-app now uses Yarn by default instead of just standard NPM. The descriptions are pretty self-explanatory, but let’s explore them in a little more detail:

yarn start

This will start up a little development web server and give you a place to start working on your application. Running this will start up a development server at http://localhost:3000/ and give you a nice little starter template:

Our default starter React project

yarn run build

“Bundles the app into static files for production.” If you’re comfortable with webpack/brunch and the build process for production sites, then you probably know what this all means. However, if all of this is Greek to you, then we’ll explain a little more. Basically, this means it’s going to take all of the Javascript code that the browser can’t interpret without any help and turn it into a smaller (“minified”) version that the browser can read and understand. It shrinks the file down as much as it possibly can to reduce the download time (probably doesn’t matter when you’re sitting on a good internet connection, but the minute you drop to 3G or worse speeds you’ll be very thankful for this!) while keeping your application running!

yarn test

“Starts the test runner.” create-react-app now ships with a bunch of tools all ready to go for you to start testing your app as you’re building it via Jest. The first time you run it you’ll probably see something like:

PASS  src/App.test.js
✓ renders without crashing (18ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 4.277s
Ran all test suites related to changed files.
Watch Usage
› Press p to filter by a filename regex pattern.
› Press t to filter by a test name regex pattern.
› Press q to quit watch mode.
› Press Enter to trigger a test run.

It’s always a great idea to run your tests as you go along, and now you get a really nice built-in way to do so (and trust me, trying to set all of this up on your own is a huge pain in the butt, so major props to the create-react-app team for this!)

yarn run eject

“Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can’t go back!” What this does is it pulls your application out of the context of the create-react-app framework and into a standard webpack build. This allows you to tweak the base create-react-app framework, either adding/removing dependencies, and perform more advanced manipulations of your app as necessary. You can think of this as a way to remove the scaffolding that create-react-app creates for you and look at the underlying project and dependency structure.

Exploring Our First App

Let’s start by looking at the first application that is created by create-react-app:

The default create-react-app project structure

It helpfully generates a readme for your project (README.md) which is in Markdown format, as well as a favicon (the icon that shows up in your browser’s address bar and is used as the icon for bookmarks and whatnot). public/index.html is the main HTML file that includes your React code and application and provides a context for React to render to. Specifically, it includes a div that your react app will show up inside. Let’s take a look at the file:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.

To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

The <div id=”root”> bit is the important part: this is where your react application gets rendered in your browser!

Next, we have our package.json file. This is what stores the lists of dependencies for your application, as well as what describes your application (the name, the version number, etc). Similarly, we also have a yarn.lock file, which is basically a locked list of all dependencies of our app.

The node_modules/ directory is where all of the dependencies get built/stored. For the most part, you shouldn’t have to fiddle with this too much.

The important directory for us as developers is the src/ directory. This stores all of our modifiable code. We’ll explore the contents of that file really quickly, too.

index.js stores our main Render call from ReactDOM (more on that later). It imports our App.js component that we start off with and tells React where to render it (remember that div with an id of root?). index.css stores the base styling for our application.

App.js is a sample React component called “App” that we get for free when creating a new app. We’ll actually be deleting the entire contents of the file and starting over! App.css stores styling targeting that component specifically. Finally, logo.svg is just the React logo.

App.test.js is our first set of tests to run against our sample App component that we start off with.

Creating Our First Component

First, open up your code in your editor of choice and also run yarn start in that directory. Next, we’ll do something fun: deleting the entire contents of App.js and App.css. Open up both files, and delete every line of them! Now that we have a nice blank start, it’s time to start learning React with ES2015!

There are two primary ways to create components in React when you’re working with ES2015 code: through functions or through ES2015 classes. We’re actually going to start off by using functions to create our components and then work our way up to using classes, explaining the differences between the two/when to choose which/etc.

Either creation method requires that React actually be imported into our component, so let’s do that first. At the top (in src/App.js), we’re going to add:

import React from 'react';

One line in and we’re already neck-deep in ES2015 code! This tells Javascript that we want to import the React library from the installed ‘react’ NPM module. That’s all! This gives us React support, JSX support, and everything we need from React to get started! Now, let’s write our hello world component!

const App = () => {
return (<div className="App">Hello World!</div>);
};

Again, some more ES2015 syntax. This creates a constant (thus the const) function (so we cannot change it) called “App”, which takes no function arguments. Any functional components that we write need to return the JSX that tells React how to create the component. Note that we wrap the JSX inside of parentheses! This is a good practice to just always do, even though you only technically need it for multi-line JSX statements. We also tell React that our component has a CSS class name of “App”. (Note: You need to use className, not class since class is a reserved word in Javascript).

Wait, What Is JSX?

If you already know what JSX is, you can skip this, but if not, here’s a quick summary:

JSX is a templating language that looks VERY similar to HTML. This allows you to write templates for your components in a way that’s very comfortable to developers already familiar with HTML, but there are a few extra things that it provides. First, you can embed any javascript inside of a JSX template by wrapping it in curly braces (these: {}). Second, some words are special and reserved, such as class, so there are JSX-specific properties/attributes/etc you need to use (such as className).

In addition, React components must only return a SINGLE JSX node at its root, so it’s very common to wrap up your components into a single div that might have multiple children underneath it.

Returning To Our Component

We have our component written, but if you look at the browser, everything is blank right now! We need to do one more thing in ES2015 to make sure other files can take advantage of any code written in this file: export.

At the bottom of our file, add the following line:

export default App;

Now, when we save the file and our app reloads automatically, you’ll see our first component show up!

Our first (very basic) component!

Embedding Stylesheets In Our Component

One trick that create-react-app does by default that is a nice thing to learn is embedded stylesheets for your components. Since we have a blank App.css file, let’s throw something in there to make our component more noticeable. Back at the top of our component (in src/App.js), below our import React line, add the following:

import './App.css';

This imports the CSS file into our component. Next, open up src/App.css and add the following:

.App {
border: 2px solid black;
text-align: center;
background: #f5f5f5;
color: #333;
margin: 20px;
padding: 20px;
}

Save the file, and then head back to your browser window and you should see something like the following:

Not a bad start for very little work!

That’s a good place to start in our application, so we’ll hop over to index.js and very quickly figure out precisely how the component gets into the browser. Open up src/index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

We already know the “import React” line, so we’ll skip that. The next bit is import ReactDOM from ‘react-dom’. This tells Javascript that we want the ReactDOM library out of the ‘react-dom’ NPM module. ReactDOM has one function in particular that we want to use: render(). Render tells React precisely HOW to throw a component into your browser. Following that we have index.css, which acts as our main global CSS file. The next line is import App from './App'. This tells Javascript that we want to import the App component from a local file called “App.js”. The “.js” can be left off completely; ES2015 is smart enough to assume that’s where it is coming from. Also, any “from” statements where the module name starts with a “./” means that you’re importing from a local file/directory, not from a module that’s installed via NPM. App.js is a local file inside of src/, so that’s why we’re using “./App” here. We also import a CSS file for the index js file. We end with a new line, import registerServiceWorker from './registerServiceWorker' which allows us access to implementing service workers for progressive web apps in our create react app! Progressive web apps are a bit outside of the scope of this tutorial series, so that’s something we’ll save for a future post, perhaps!

Now we have our render call. Render is a function that takes two arguments:

  1. Which component to render
  2. Where to render that component

In our case, we declare the component using JSX. Since our component name was imported as “App”, we can reference that app inside of a JSX template as if it were an HTML tag:

<App />

Note: All tags in JSX need to be closed, either inside of the tag such as above or like this:

<App></App>

Finally, we look up where to render the component on the page with the call to document.getElementById('root'), which tells javascript to find an element on the page which has an ID of “root”.

Conclusion

Congratulations! You now have the start of a basic functional component in React with very little work! You have webpack and babel and everything else all figured out and installed for you but without a lot of the fuss or bother! This is a very nice, very clean way to get started with React development. In future tutorials, we’ll flesh out example a lot more by adding components via ES2015 classes, as well as adding concepts of state and props into our components. We’ll also discuss using the build and eject commands and what they mean!

Next Post in this Series

Check out my new book!

Hey everyone! If you liked what you read here and want to learn more with me, check out my new book on Elixir and Phoenix web development:

I’m really excited to finally be bringing this project to the world! It’s written in the same style as my other tutorials where we will be building the scaffold of a full project from start to finish, even covering some of the trickier topics like file uploads, Twitter/Google OAuth logins, and APIs!