How should we structure our React code? (1/2)
Tags: javascript, react, codestructure, beginners
Published: 2019-12-30 11:33:18

*Note: This post doesn't portray that this is the only way to structure the code. There are many other great ways to do it. In fact, this method might have already been followed by most of you. This post also considers that you have some background knowledge about React and its ecosystem, also some common terminologies used in the web community*


### This is a two-part series, the next part will be posted soon.


## Only to React?

Although the title says React code but this method can be applied across other front-end stacks too. I have used this method to build a Vue application too and it worked like a charm for me. I used React for this post because that's where I started for the first time.


## How this will help?

I have worked in multiple teams and products. The major problems faced by a lot of new joiners is to understand the code structure. The first impression you make on your new joiners could be the last impression you make of the capabilities of your tech team. This method will help new joiners understand the code structure with the utmost simplicity. 

Also, by following this way of code structuring, you would be able to avoid a lot of merge conflicts. Adding new features would be a cakewalk for any web-dev on your team. Also if you want to extract some code out to create a library out of it, you can do that too in very less time.

More in detail in the next part of this post series.


## Why not use already built boilerplates?

We did start with cloning the best boilerplates out there but eventually had to tweak them accordingly to fit into our team's vision. So we ended up deleting a lot of code from that boilerplate code. The most common problem we faced while using some boilerplate code is to dump all the unnecessary code and configuration that isn't needed and while doing that, most of the time the code breaks, so we had to fix all the problems instead of building new features.

So we created our own boilerplate, just in case we need to kickstart a new front-end project in the future. I am saying that you should also stop using boilerplates created by well-known devs but this is just our strong opinion about what we want in our day-to-day coding sessions.

Creating your own boilerplate can also help you incrementally add libraries that you might later need while writing your production code. We like to keep our boilerplate code as lean(fewer libraries from the start) as possible because we don't want our bundle size to be high from the onset of our project.


## Get started

First, let's use `create-react-app` to scaffold our react app. We all know what does it do(if not that read it [here](https://create-react-app.dev/)). I am using it because I don't want this post to be longer than 2 posts, not deviating from our main topic and I am very lethargic too(truth revealed).

So after executing following command in the terminal in your workspace
```bash
npx create-react-app my-app
```

It creates a folder my-app with the following file structure,
![File-Structure-1](https://thepracticaldev.s3.amazonaws.com/i/f7g4xp5kd8tqoxaeu5ju.png)

Listing each directory and its uses,
1. `node_modules` for your npm dependencies.
2. `public` directory contains all your static assets such as favicon, images, robots.txt, and your index.html which will get exported with right bundle names when you build your app.
3. `src` directory contains all your application code.
4. `build` directory will get created once you build the app. It contains all the transpiled js bundles, css, index.html, images, and favicons in it.

For the sake of this post, we will focus our attention on `src` directory.

Let's look at what files the `src` folder contains. 
1. The first file that loads into action is `index.js` which imports every other needed file to bootstrap this application. 
2. `index.css` contains global css styles. 
3. `App.js`, `App.css` and `App.text.js` are all related to the App component which is our root component. Everything that renders on our screen when we run `yarn start` command is in the App component.
4. Rest of the files you can ignore for now especially `serviceWorker.js`

![CRA-1](https://thepracticaldev.s3.amazonaws.com/i/zcntrxaeet4osul92bmi.png)

We can add all our Application code in our App Component file but it would give you nightmares later on. Also, we would want our SPA to have routes for our application to react to URL changes. 

Let's consider we want to build an application which has 4 routes
1. Login
2. Dashboard
3. Listing
4. Profile

When the user first lands on our application, he/she sees the login screen first, after login we redirect our app to Dashboard where the user can navigate to Listing and Profile. Don't want to overdose you with what features each route will have. This post is already quite long for you and I don't want you to get bored.

Moving on, we will need some kind of routing logic for our routes. I am using `react-router-dom` for representational purposes. First I add it as a dependency using the command `yarn add react-router-dom`. Make sure it has been added to your `package.json` dependencies.

I don't like to keep the App component lingering around in the `src` folder like that, I will create a `screens` folder. I will come back to why I named it like that. Inside that `screens` folder, create another folder named `App`. Inside the `App` folder create a file named `index.js`, this we will use for exporting App code to whoever wants to consume it.

Now you create a `components` folder under `src/screens/App` folder. Move `App.js`, `App.css` and `App.test.js` files to recently created `components` folder. Now your file structure will look like this.

![File-Structure-2](https://thepracticaldev.s3.amazonaws.com/i/1spde462zedk9ebs37pq.png)

I will now export the App component from `src/screens/App/index.js` file.

![File-Code-1](https://thepracticaldev.s3.amazonaws.com/i/a0ur1r5n6o6or83lxiat.png)

I will now delete the entire jsx code from App component to make things easier for us.

![File-Code-2](https://thepracticaldev.s3.amazonaws.com/i/3vnw95qzbcep541m8yjm.png)

We will make file location changes for App component import in the `src/index.js` file. Also, removing the references to `index.css` and `serviceWorker.js` files which we don't need in our context. The `src/index.js` file looks like this.

```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import App from 'screens/App';

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

Now if you save and look at the application, it will be just a white screen with text - App component written in the top center of the screen.

Now let's create another folder under `src` directory named `shared`. This directory will contain all the shared utilities, constants, components, and other stuff that needs to be shared with your entire Application code. Right now I am creating constants for our routes.

![File-Code-4](https://thepracticaldev.s3.amazonaws.com/i/hvxbtjbjym5sgquwg652.png)

Now we go ahead and create route links in our App component. We import our constants and create some anchor tags to those routes.

Before we do that, we need to solve add a file `.env` at the root. Some of you must have seen a discrepancy in one of the changes I made above while editing `src/index.js`. I had referenced App component like this,
```javascript
import App from 'screens/App';
```
And not like this,
```javascript
import App from './screens/App';
```

It's because I added the `.env` file at the root folder which helps us resolve modules in the `src/` folder without having to reference files using `../../../` from deep inside the file directory. Create a file `.env` at the root and paste the following content in it and then restart our application using `yarn start`.

```bash
NODE_PATH='src/'
```

As a direct result of this, we can now reference shared constants(also any future shared utility) from anywhere our application like following,

```javascript
import routeConstants from 'shared/constants/routes';
```
Without worrying about those `../../../`

After this, we import routeConstants into our App component and add 4 Link tags from the `react-router-dom` library just below the App title. I also added a bunch of other components required for our routes to work.

```react
import React from 'react';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";
import './App.css';
import routeConstants from 'shared/constants/routes';

const {
  LOGIN,
  DASHBOARD,
  LISTING,
  PROFILE,
} = routeConstants;

function App() {
  return (
    <Router>
      <div className="App">
        <h1>App Component</h1>
        <ul className="App-nav-list">
          <li className="App-nav-item">
            <Link to={LOGIN.route}>{LOGIN.name}</Link>
          </li>
          <li className="App-nav-item">
            <Link to={DASHBOARD.route}>{DASHBOARD.name}</Link>
          </li>
          <li className="App-nav-item">
            <Link to={LISTING.route}>{LISTING.name}</Link>
          </li>
          <li className="App-nav-item">
            <Link to={PROFILE.route}>{PROFILE.name}</Link>
          </li>
        </ul>
        <Switch>
          <Route exact path={LOGIN.route}>
            <h1>{LOGIN.name}</h1>
          </Route>
          <Route path={DASHBOARD.route}>
            <h1>{DASHBOARD.name}</h1>
          </Route>
          <Route path={LISTING.route}>
            <h1>{LISTING.name}</h1>
          </Route>
          <Route path={PROFILE.route}>
            <h1>{PROFILE.name}</h1>
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

export default App;

```

Now our App looks like this,

![App-1](https://thepracticaldev.s3.amazonaws.com/i/29glwp1x2x3s1lt8xb86.gif)

Although I dumped everything inside the App component here. In the next post, I will start distributing each route component code into its own separate space so that you get the gist how the final file structure actually works.

Please do leave comments about the pace, language as well as contents of this post. This is my first post and I might have been grammatically incorrect. Also please do comment if you are eagerly waiting for the next post, it will encourage me to post the next one early. :)


## To be continued...