So it turns out that React itself is pretty simple. It’s just a library that takes Element
objects, and renders them to the DOM!
Of course, real world React apps use JSX, and JSX needs a build system. To really understand how React works, you’ll need to understand what happens before the first component is rendered. So with this in mind, let’s take a look at the four files that Create React App uses to start your app.
src/App.js
This file exports your app’s main component.
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
There’s nothing special about this file — you could change its name, or even remove it completely. However, React apps often follow the convention of calling their top-level component App
, so Create React App is kind enough to start you off with one. We’ll go into more detail on the App
component in a later lesson.
src/index.js
This file is special — it’s your app’s entry point, and it will be run as soon as your app has loaded. By default, it’ll import the default component exported by src/App.js
, and render it with ReactDOM.render()
.
The other interesting thing about this file is that imports serviceWorker
, and then calls its unregister()
method:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change// unregister() to register() below. Note this comes with some pitfalls.// Learn more about service workers: https://bit.ly/CRA-PWAserviceWorker.unregister();
This line and the associated serviceWorker.js
file are completely safe to remove, because service workers are completely optional. In fact, while service workers can slightly speed up your app, they also can cause your app to show out-of-date content. Because of this, I’d recommend avoiding service workers at least until you’re comfortable with the basics of React itself.
public/index.html
This is a template for the index.html
file that contains your app’s root
div, along with the <script>
tags that load your app’s code. It’s mostly just a plain old HTML file — with a couple of differences.
Interpolated constants
This file allows you to interpolate some environment variables (but not all). In particular, it allows you to interpolate a PUBLIC_URL
environment variable, which is how you can specify fully qualified URLs inside of the page <head>
.
Injected script tags
Create React App will inject your app’s <script>
tags at the end of this file. Of course, you can still add your own script tags too — for example, for Google Analytics or Stripe.
You won’t often need to touch this file unless you want to change the tags within your document <head>
. Speaking of which, the one change you’ll often want to make in this file is the <title>
tag. If you’re following along with Create React App, try this out by changing the title to something fun:
<title>Skynet</title>
package.json
This file contains configuration for npm
— the Node.js package manager. But why would you need to configure npm?
Quiz time! Do you remember how to start the development server?
$ npm run start
That’s right! To start the development server, you use npm
— despite the fact that the development server is part of Create React App (and not Node.js). Huh, that’s odd. Obviously, there’s something going on here, and you may already have an idea of what it is.
scripts
If you take a look inside package.json
, you’ll find the following:
{
"scripts": {
"start": "react-scripts start"
}
}
This scripts
object tells npm how to respond when you call npm run <scriptname>
. For example, given the above configuration, calling npm run start
will cause npm to look for and execute a shell script called react-scripts
, passing in start
as its first argument. And if you don’t have a script called react-scripts
installed globally, npm will also look in your project’s node_modules/.bin
directory — which happens to contain a react-scripts
file.
All of this is a bit of a mouthful, so here’s the simple version:
When calling npm run [scriptname]
, the corresponding script listed in package.json
will be run from the node_modules/.bin
directory.
So what other scripts does Create React App’s package.json
include? You can find out the details in the generated README.md
file, or on the Create React App website. But here’s a quick overview:
npm start
launches the development server at localhost:3000
.npm test
launches an interactive runner for your app’s automated tests.npm run build
builds a distributable version of your app, placing the result in the /build
directory.npm run eject
basically copies-and-pastes create-react-app’s source into the current project. This allows you to modify the build system, but also significantly increases the amount of maintenance required, so you’ll want to avoid using this unless absolutely necessary.dependencies
After running npm init react-app
, your generated package.json
will list a few dependencies:
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1"
}
You saw that last script right? It can’t be a coincidence that react-scripts
is both listed as a dependency, and also available under node_modules/.bin
?
So here’s how this works. When you install a dependency with npm
, that dependency can ask npm to install some files into node_modules/.bin
. As you may expect, the react-scripts
package has asked npm to place a react-scripts
file into node_modules/.bin
. And that’s why it’s possible to use react-scripts
within the scripts
object — even though it’s not installed globally.
Of course, while dependencies can register scripts
, they’re far more frequently used to package up functions and components — which your code can then import
. In fact, that’s how React itself is loaded into your app:
dependencies
object in package.json
specifies what goes in node_modules
npm install
command installs those packages into node_modules
, andimport
statements without a leading ./
refer to code in node_modules
If any part of this doesn’t make much sense, then that’s okay — you can always look it up in the Create React App and npm documentation if you need to. The main thing to take away right now is that these files exist, and that you can edit them if you need.
And with that out of the way? It’s time to dive into the wonderful world of state!