Create React App and React Router 4 Developer Workflow

“MacBook Pro showing programming language” by Émile Perron on Unsplash

Prerequisites

Run time environment and package manager: Node, npm and yarn
Code editor: VS Code is my preference https://code.visualstudio.com/
Terminal App: Hyper is my preference https://hyper.is/

Install and Setup npm scripts

npx create-react-app my-app

2. cd into the app folder and then run the command for ESLint Initialise

Use the popular airbnb style guide and select .json for the eslint file. Select yes for React and to install peerDependencies

yarn add eslint --dev
./node_modules/.bin/eslint --init

Install prettier and eslint plugins

yarn add prettier eslint-plugin-prettier eslint-config-prettier --dev

ESLint Config file with Prettier Integration for formatting
It is better to do it in the ESLint file, instead of using the Prettier plugin for your code editor. Because this way it is more portable, and you can debug using the command line as well as, transfer your workflow to other systems by just using the .eslintrc.json file.

Integrating with ESLint · Prettier https://prettier.io/docs/en/eslint.html

GitHub — prettier/eslint-plugin-prettier: ESLint plugin for prettier formatting https://github.com/prettier/eslint-plugin-prettier

GitHub — prettier/eslint-config-prettier: Turns off all rules that are unnecessary or might conflict with Prettier. https://github.com/prettier/eslint-config-prettier

If there are any problems you can always, revert to using the Prettier code editor plugin and setup.

Copy the below code, into your .eslintrc.json file

{
"extends": [
"airbnb",
"prettier/react"
],
"plugins": [
"prettier"
],
"env": {
"browser": true,
"jasmine": true
},
"rules": {
"react/jsx-filename-extension": [
1,
{
"extensions": [
".js"
]
}
],
"react/prefer-stateless-function": [
0,
{
"ignorePureComponents": true
}
],
"prettier/prettier": [
"error",
{
"trailingComma": "none",
"singleQuote": true,
"printWidth": 100
}
]
}
}

Add the linting script to the package.json file

"lint": "eslint ."

Fix ESlint errors

registerServiceWorker.js comes with create-react-app and we should not have to worry about linting it, just in case it causes errors.

Create a .eslintignore file in the root directory (the same folder with the .eslintrc.json file in it. And add src/registerServiceWorker.js to the first line and save.

CLI Run Commands

Run the App and styles from one terminal window. And do the linting in another window. The App should be live at http://localhost:3000 and linting should be working in your javascript files now.

Running the App

yarn start

Linting .js files

yarn lint

Creating a production build

yarn build

React.js Project Folder Setup

css folder — used for css files
components folder — used for javascript component files
assets folder — used for media such as images, videos, icons etc…

2. Delete the files index.css and logo.svg. Delete the index.css import code in index.js

import './index.css';

3. Remove references of logo in App.js

import logo from './logo.svg';<img src={logo} className="App-logo" alt="logo" />

4. Decide whether you want to use Stylus or Sass as your preprocessor. Move App.css to the css folder. Create either a App.styl or App.scss file inside it.

5. Delete all of the styles inside of App.css and replace with the below, example boilerplate. Duplicate the code into your App.styl or App.scss file.

Alternatively you can write your own CSS this is only an example so that you can see it work.

:root {
--grey: #343436;
}
html {
font-size: 62.5%; /* font-size 1em = 10px on default browser settings */
}
body {
font-size: 1.6rem;
}
.container {
max-width: 1300px;
width: 100%;
}

Install Stylus or Sass

Stylus setup

yarn add stylus

Put (Under scripts in package.json)

"styles": "stylus -w ./src/css/App.styl -o ./src/css/App.css",

When we run this script it will compile every .styl file in the ./src/css folder, then save the compiled css in ./src/css folder every time we change a .styl file.

Make sure that the folders tree looks like below

└── src
└── css
├── App.css
└── App.styl

Sass setup

yarn add node-sass

Put (Under scripts in package.json)

"styles": "node-sass -w ./src/css -o ./src/css",

When we run this script it will watch every .scss file in the ./src/css folder, then save the compiled css in ./src/css folder every time we change a .scss file.

Make sure that the folders tree looks like below

└── src
└── css
├── App.css
└── App.scss

Update the import code in App.js to the below

import ‘./css/App.css’;

Install concurrently or npm-run-all

They allow you to run multiple scripts at the same time.

concurrently setup

yarn add concurrently

Put (Under scripts in package.json)

"watch": "concurrently \"yarn start \" \"yarn styles\"",

npm-run-all setup

yarn add npm-run-all --save-dev

Put (Under scripts in package.json)

"watch": "run-p start styles",

Running the App with styles

Run the command yarn watch to run the scripts and styles at the same time, no need for multiple terminal windows. One for scripts and one for styles etc… The App.styl/App.scss file will be the main file used for doing the CSS, so write your code in there. It will then convert and update the App.css file. You can do a test by adding a background color to the body to make sure that its working properly.

Install normalize.css

yarn add normalize.css

Import normalize.css into index.js

import 'normalize.css';

React App Folder Tree

└── my-app
├── README.md
├── node_modules
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── src
│ ├── App.js
│ ├── App.test.js
│ ├── Router.js
│ ├── assets
│ ├── components
│ ├── css
│ │ ├── App.css
│ │ └── App.styl
│ ├── index.js
│ ├── registerServiceWorker.js
│ └── views
└── yarn.lock

Optional Installs

Documentation for using styled-components in React https://www.styled-components.com/

Install Styled components

yarn add styled-components

Import into corresponding .js file when using

import styled from 'styled-components’;

React Router 4 Install and Setup

Install React Router

yarn add react-router-dom
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import App from './App';
const Router = () => (
<BrowserRouter>
<Switch>
<Route exact path="/" component={App} />
</Switch>
</BrowserRouter>
);
export default Router;

3. Update the index.js file in the root of the src folder so it looks like the below

import React from 'react';
import ReactDOM from 'react-dom';
import 'normalize.css';
import Router from './Router';
import './css/App.css';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<Router />, document.getElementById('root'));
registerServiceWorker();

Example setup with pages and 404 routes

App.js is the homepage, and subsequent pages are to be created in the views folder. Create components and put them in the components folder. Then import those components, into the pages you create in the views folder.

The NotFound.js file is the 404 page, which is the page that you get redirected to, when you have an invalid url in your search box.

Router.js file

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import App from './App';
import About from './views/About';
import NotFound from './views/NotFound';
const Router = () => (
<BrowserRouter>
<Switch>
<Route exact path="/" component={App} />
<Route exact path="/about" component={About} />
<Route component={NotFound} />
</Switch>
</BrowserRouter>
)
export default Router;

About.js file http://localhost:3000/about

import React, { Component } from 'react';class About extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">About Page</h1>
</header>
<p className="App-intro">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis in urna sed nisl faucibus
suscipit. Proin diam erat, accumsan vel tincidunt id, tristique vel odio. Etiam ex lectus,
eleifend nec dignissim vel, lacinia eget diam. Pellentesque pulvinar imperdiet tortor,
eget varius erat tempus ut. Nunc dictum enim ac massa pharetra facilisis. Vestibulum at
pulvinar erat, vel venenatis purus. Integer ut vulputate augue, vitae molestie mi. Aliquam
imperdiet, est non pellentesque consequat, mauris elit rutrum nulla, aliquam pellentesque
arcu mi ac augue. Nulla iaculis eget mi ut cursus. Nullam nec ligula tincidunt, posuere
est vitae, placerat turpis. Vestibulum pellentesque, lorem quis dignissim tristique, ex
lacus sodales ligula, nec blandit ex nisl ac lorem.
</p>
</div>
);
}
}
export default About;

NotFound.js http://localhost:3000/foobar

import React, { Component } from 'react';class NotFound extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">404 Page Does Not Exist</h1>
</header>
</div>
);
}
}
export default NotFound;

Page Navigation

The href attribute is required on an anchor. Provide a valid, navigable address as the href value. Add a href address to the link tag like below.

<Link href="/" to="/">
Home
</Link>

React App and React Router 4 Folder Tree

└── my-app
├── README.md
├── node_modules
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── src
│ ├── App.js
│ ├── App.test.js
│ ├── Router.js
│ ├── assets
│ ├── components
│ ├── css
│ │ ├── App.css
│ │ └── App.styl
│ ├── index.js
│ ├── registerServiceWorker.js
│ └── views
│ ├── About.js
│ └── NotFound.js
└── yarn.lock

*Bonus section*

Scroll to top Restoration

React Router: Declarative Routing for React.js https://reacttraining.com/react-router/
React Router: Declarative Routing for React.js https://reacttraining.com/react-router/web/guides/scroll-restoration

Most of the time all you need is to “scroll to the top” because you have a long content page, that when navigated to, stays scrolled down. This is straightforward to handle with a <ScrollToTop> component that will scroll the window up on every navigation, make sure to wrap it in withRouter to give it access to the router’s props:

The example code below works

import React from 'react';class ScrollStateTop extends React.Component {
componentDidMount(prevProps) {
window.scrollTo(0, 0);
}
render() {
return null;
}
}
export default ScrollStateTop;

Document HTML Head and Meta tag setup (SEO)

React scripts for dynamic head meta (Choose one of them)

GitHub — nfl/react-helmet: A document head manager for React https://github.com/nfl/react-helmet

GitHub — s-yadav/react-meta-tags: Handle document meta/head tags in isomorphic react with ease. https://github.com/s-yadav/react-meta-tags

GitHub — kodyl/react-document-meta: HTML meta tags for React-based apps. Works for both client- and server-side rendering, and has a strict but flexible API. https://github.com/kodyl/react-document-meta

You need to have different meta descriptions on each page, its good for SEO.

👨🏿‍💻 Software Developer @CGI_Global 🖼 Content Creator. Sharing the mindset and content so you work hard to grow stronger than your past self ☯️