6 - Structure of a React app

Decomposing an app in smaller, manageable pieces is one of the foundations of React. The file.io app that we wrote in vanilla JS had a single HTML/JS file that takes care of uploading files. Similarly, there was a single HTML/JS file that takes care of downloading files. While you can still divide legacy apps into more manageable, a lot of times the apps do follow a monolithic structure.

Everything that can be present on the functionality 1 page is present in func1.html. Same for func2.html.

React, on the other hand, doesn't recommend using a monolithic structure. React suggests/recommends that an app should be broken down into small and reusable pieces. This is one of the foundations of React.

The official definition of React itself talks about this:

React lets you build user interfaces out of individual pieces called components. Create your own React components like Thumbnail, LikeButton, and Video. Then combine them into entire screens, pages, and apps.

In the React world, you won't see long HTML files. You won't see long JS files that contains spaghetti code of everything that goes on the page they are supporting. Instead, you'll see numerous small pieces that are attached together to form the page. On a fairly complex production grade app, it is easy to see hundreds of pieces (or components). This is like a jigsaw puzzle. The small pieces come together to solve the puzzle, or build a page in this case.

The small pieces are called components.

Components are independent and reusable bits of code. They serve the same purpose as JavaScript functions, but work in isolation and return HTML. Components come in two types, Class components and Function components. (Credit: w3school).

Now, let's open the code produced in the first-react-app folder which was created by the create-react-app tool.

There are a good number of files in the generated app. We don't have to worry about most of them. In fact, we're going to delete most of them in the next sections.

The interesting parts are:

  • public/index.html

  • src/index.js

  • src/App.js

First, the index.html. You would expect the index.html to contain some HTML code related to the landing page we saw when ran the app? You can go up in this page to see the screenshot. You'd be surprised that the index.html contains nothing like that. The file is basically empty. Here is the body part of the index.html:

  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>

That's all in the index.html. An empty? You might wonder what's going on. Don't worry, as we'll find the answer pretty soon. Recall that React recommends small, manageable pieces. Putting things in index.html is not the recommended way. The index.html will get some code but only after the build step. We don't have to worry about it at all.

The next interesting file is index.js:

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

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

This file is the start of the magical world of React. You might get confused to see <App />. This is the proprietary syntax of React called JSX (we'll cover JSX in the next section).

For now, we can see that the code is getting the root where it has to mount the React pieces. The API ReactDOM.createRoot creates a React component. Once a root element is created in React, it can be rendered in the browser using the render API provided by the component. In this case, the only thing getting rendered is App.

The index.js file is the entry door of the React world.

The only interesting thing remaining to see is the App.js file:

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>
          I'm learning React!
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

In this code, there is an App component that's getting created. There is a function called App that returns HTML (with some weird things in it, like {}). At the end, the component is offered as the default export.

Structure of components

There are two types of components in React:

  • Class component

  • Function component

For beginners, function component is the easiest to learn. The class components are for a more advanced use-case where more granular control is required over React's functioning. All the examples in this book uses function components. For beginners, there is no reason to learn class components instead of function component.

A function component has three interesting parts:

  • Imports: Any dependencies like other components, CSS, etc.

  • JS function: Every function component has a regular JS function that always returns some JSX. You can do many things in that regular JS function. But the return is always a JSX.

  • Export: The JS function of the component is offered as the default export

In the React world, each component is present in its own file (SomeComponent.js). The file name usually starts with a capital letter like App.js, Header.js, Footer.js, etc.

Now, let's take the code of App.js (given to us by the create-react-app), and divide it into parts:

The app produced by create-react-app is way too simple. There is just a single component: App. This is a good start. However, even the smallest of the app will have more than one component.

React doesn't dictate any app structure. The standard practice is to place all the components (except App.js) inside a components directory. As mentioned earlier, the name of the file and the function starts with a capital.

Let's make change in the App.js by adding two of our components. The first component is called Component1 and the second one is called Component2. For now, both the components are going to return an HTML containing a simple <h1> with the component name.

These two components can now be included in the generated App.js. It is very simple to add them. Simply import them, and use them inside the return block of App.js. At this point, we're going to remove the other parts that were given by the generator.

That was fairly simple. The components are imported and then used in the returned JSX (again, don't worry about it right now). If the dev server is still running, you can go to the browser to check out the new app.

Component CSS

Just like functionality gets divided into small & manageable components, the app CSS also gets divided into small & manageable pieces.

There are two places to keep the CSS files:

  • Inside common CSS directory: Some applications have a common CSS directory where all the CSS files are present. The individual components import them as needed.

  • With the component: A more common approach is to place the CSS along with the JS file. For example, Component1.js and Component1.css will be in the same place. This is a more common style in the React world.

As we've just written two new components, let's also add CSS for both of them. The CSS files will be placed along with the components in the components/ folder. The updated code is:

Note: A CSS file can be imported using regular import statement

A quick refresh in the browser shows that we're doing it right:

If you've reached till here by following the exercises, then pat yourself. You've just written your first React code. This is a big achievement in itself. Take a break and then start the next section later.

--

That was all about the first foundation of React: Components. The next section will be a quick introduction to JSX. We'll take it up from here and add some more code to the Component1 and Component2 that we've built here.

Last updated