Company logo | Codica

In 2019, the web faces new complex issues and we can see innovative technologies and solutions emerging every day. One of the most popular and relevant programming tools to build an application of any scale and complexity is ReactJS.

This UI library greatly simplifies the development process and allows you to manage the program state efficiently and smoothly. However, in order to start creating the real web masterpieces, you need to understand where to start, right?

In this article, we want to show you the most popular open-source solutions that will help you with starting ReactJS development effortlessly. Also, we will provide you with our best practices on the general React-Redux project structure to have a better understanding of application architecture.

Why choose ReactJS for frontend development

For the past five years, React has been developing and growing rapidly. According to Google Trends, the total domination of this library began in 2017 and is only increasing. Its opponents Angular and Vue are actually far from the popularity and community support of React.

Google trends comparison of React vs Vue vs Angular

Just take a look at the comparison table made by the State of JavaScript in 2018:

Comparison of Front-end frameworks by Stateofjs 2018

Source: Stateofjs.com

To underscore the support and popularity among the community, it has to be said that 972,884 websites are developed using React and this number keeps growing (by 1.62% for the last month at the moment of writing). In comparison, there are 488,677 websites in Angular and 148,347 websites in Vue.

You may find interesting: How We Built a Slack Bot for Time Tracking with Vue.js and Ruby on Rails

Furthermore, currently React is the most loved and wanted web framework. The majority of developers say they want to work exactly with this web tool if they do not already. It was proven by StackOverflow in their Developer Survey Results 2019.

Most wanted frameworks by StackOverflow

Thus, does the popularity of React mean that it is much easier to create web products using this tool? Not as such. Web development in 2019-2020 faces new challenges and problems, and there are tons of ways to solve them even within one paradigm.

However, ReactJS is extremely popular nowadays as there are many additional tools that, in combination with React, can solve most of your problems. Let’s take a look at the most popular solutions used in ReactJS development.

Related reading: Main JavaScript Development Trends.

React development tools: CRA vs Next.js vs Gatsby

To begin with, we will tell you about such ready-made solutions as create-react-app (CRA), Next.js, and Gatsby. They allow you to start developing your ReactJS project without wasting time on the setup process, providing a basic structure template and minimal functionality. This way, you will be able to launch fast and smoothly. Further, of course, you can change your application structure configuration if necessary.

We are going to mention SSR (Server Side Rendering) and CSR (Client-Side Rendering) many times. For this reason, we want to define the difference between Server-Side Rendering and Client-Side Rendering.

Client-side rendering

Usually using ReactJS, your browser loads a minimal HTML page, and the content is filled with JavaScript.

Server-side rendering

The content is generated on the server, so your browser can load a page with an already existing HTML content. Content updates are still processed in the browser.

Let’s now proceed to the detailed overview and comparison of the available React development tools, covering their benefits and drawbacks, peculiar properties, and core differentiating features.

CRA

CRA, or Create-react-app, is a tool designed by Facebook developers, creators of React. This solution gives you a quick start while building ReactJS applications. It saves you from the configuration process by generating a maintainable and comprehensive React App scaffold. It installs all the default dependencies, packages, and creates a default directory structure.

CRA is clear and it produces HTML code required to be rendered on the front-end. Thus, when you take a look at the source code before rendering, you can see it’s basically a few .js files and an empty div. These .js files inject content into that div in the browser (client-side rendering). All the heavy lifting is done in the browser.

Here is the set of command lines that will help you quickly start a React app with CRA:

npm install -g create-react-app
create-react-app my-app
cd my-app/
npm start

To conclude, this tool is a perfect solution for a fast ReactJS app setup. You can skip such time-consuming issues as configuration, installing dependencies, packages, and creating a project structure.

Related reading: 4 Useful Git Commands That Will Make Your Life Easier.

Next.js

Shortly, Next.js is a lightweight framework that gives you an opportunity to build server-rendered and static React.js apps simply and smoothly. It requires a server to have a possibility to run and it produces HTML on runtime. So each time a new request comes in, it creates a new HTML page from the server.

Many promising and growing tools (similar to Next.js) are not so popular. What is the reason for this? The matter is that traditionally many JS frameworks are not that good with static HTML code generation. Under modern conditions, such UI libraries as ReactJS are perfectly supported by the means of server rendering. However, to use that feature, you need to have a deep understanding of bundlers’ and source builders’ operational aspects.

So, the recent emergence of such PWA frameworks as Next.js was a serious step toward the widespread adoption of the Progressive Web Application technology. It made the use of such frameworks a simple and enjoyable exercise.

Here you can see the stages of work with a React app using Next.js:

Next.js workflow

Below are some key features that this framework provides:

  • Server-Side Rendering
  • Static files creation
  • Automatic code splitting
  • Prefetching
  • Hot Module Replacement and Error Reporting.

Here is the command line which allows you to quickly start a React application with Next.js:

npm install --save next react react-dom

Then add scripts to your package.json:

{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}

Finally, run the following command:

npm run dev

To conclude, Next.js is a solid tool for building server-rendered React apps. It allows you to avoid setting up Webpack, React-Router, React and React-DOM (available out-of-the-box) that take your time. Finally, you get improved SEO and first-page load performance.

Gatsby

To be clear about Gatsby, we should repeat that create-react-app provides Client-Side Rendering, Next.js provides Server-Side Rendering, but Gatsby is an open-source framework that refers to blazing-fast Static Site Generator.

In case you are new at static site generation, let’s define what it stands for. Thus, the static side generators are those which produce HTML code during the “build” stage. Actually, it may be performed by fetching data from some APIs, markdown files, etc. It’s important to remember that everything is done in the “build” process.

Here’s how you can quickly start a ReactJS application with Gatsby:

npm install -g gatsby-cli
gatsby new gatsby-site
cd gatsby-site
gatsby develop

To conclude, Gatsby solves most of the issues affecting website performance out-of-the-box. When you understand the subtleties to customize it to your needs, you can get 100% of performance, which will significantly affect the site’s search engine results.

CRA vs. Next.js vs Gatsby: a brief comparison

To summarize all the aspects of the discussed ready-made solutions, below you can find a brief comparison table.

Comparison table of CRA vs Next.js vs Gatsby
CriteriaCreate-react-appNext.jsGatsby
Final stageBrowserServer‘Build’
Search engine optimizationLowMediumMedium
Deployment complexityMediumMediumEasy
Learning curveLowMedium
Additionally required: React.js + several Next.js APIs
High
Additionally required: React + GraphQL + several Gatsby APIs
OutputBundle JavaScript filesHTML (initial load) + Code split chunksStatic build files (HTML+CSS+JS)

Thus, we have shown you what open-source solutions are available to start developing ReactJS applications quickly and without a large setup. The framework or tool to choose depends on the technical need and your personal preferences.

You may find interesting: The Power of CSS Processors in Web Applications Development.

Best practices on React-Redux project structure

At Codica, we have been developing complex React applications for many years, and our team decided to share the experience in our own React-Redux Best Practices on GitHub. There we specify our vision on how to better organize the project breakdown based on create-react-app (CRA).

In this section, we want to share our base recommendations on how to structure your project files and code so that your application stays maintainable as it scales, based on our experience.

To put it shortly, CRA is a flexible tool that allows you to structure your project code as long as the index.js file is available in the root of the /src directory. Small projects don’t require a sophisticated structure. Thus, you can put all your components in the /src directory. However, this option is not suitable for large projects.

Firstly, we decided to separate React and Redux into different folders. Thus, it simplifies the process of applying any changes or adding a new feature. Redux-specific code (reducers, actions, action types) is split by feature-first pattern Re-Ducks. Here is an example of a project structure we use in practice:

src/
├── state => redux specific code (Re-Ducks)
|   ├── ducks/
|   |   ├── duck/
|   |   |   ├── types.js
|   |   |   ├── actions.js
|   |   |   ├── selectors.js
|   |   |   ├── reducers.js
|   |   |   ├── tests.js
|   |   |   ├── index.js
|   utilities/ => global constants and helper functions
|   views/
|    ├── routes/       => base router
|    ├── components/   => feature-first components
|    ├── pages/        => layouts, related to routes
|    ├── styled/       => StyledComponents
|    └── UI/           => reusable components

We prefer to create the React components first and then the corresponding Redux code. It allows us to have a general understanding of the data requirements.

The /ducks directory has a fixed pattern. We use a modified version of the ducks pattern to organize our Redux code:

ducks/
├── duck/
|   ├── actions.js
|   ├── reducers.js
|   ├── types.js
|   ├── utils.js
|   ├── selectors.js
|   └── index.js
└── index.js

Now, let’s discuss each /duck folder file to understand why is it important and what does it stand for.

Project structure files

types.js

This file contains string literals for our action types. It provides an easy reference to the actions available. These strings are exported as an object literal which can then be imported into your reducers and action creators instead of hard-coding them. Although maintaining a separate file that contains the action types is optional, it is highly recommended in organizing the structure of your project files.

// types.jsexportconstSOME_YOUR_TYPE="SOME_YOUR_TYPE";

actions.js

In this file, we define all the actions. Actually, some developers tend to separate async actions and action creators, but we don’t think it is pretty crucial.

// actions.jsimport types from'./types.js';// action creatorconstsomeAction=payload=>({type: types.SOME_YOUR_TYPE,
  payload
});

Actually, we use redux middlewares such as redux-thunk or redux-promise-middleware for dispatching async actions.

reducer.js

The reducer is required to update the state. We create a single reducer for each action using createReducer. We use this command to create reducers, not the basic switch-case template. The matter is it's very useful, for example, if you need to scope out part of a reducer to use variables with the same name in several case statements.

// reducer.jsconst someReducer =createReducer(initialState)({[types.YOUR_ACTION_TYPE]:(state, action)=>{return{...state,some_prop: action.payload
    };},[types.SOME_ANOTHER_TYPE]:(state,{payload:{ data }})=>({...state,
    data,loading:false}),[types.MAY_BE_YOU_WANT_RESET]:(state, action)=>({...initialState
  })});

selectors.js

In Redux, a selector is a piece of logic that gets a specific piece of state from the store. Additionally, a selector can compute data from a given state, allowing the store to hold only basic raw data. Selectors are usually used as a part of the binding between the store and the container components. For example, the mapStateToProps function that’s passed to React-Redux connect function is a place where selectors would be used to select the needed parts of the state for a container component.

In order to create selectors, we use the Reselect library. This library is not the only way or the requirement to create selectors, but it provides a few benefits in terms of developer experience and performance:

  • Selectors created through a createSelector function are memoized. It means that the function remembers the arguments passed-in the last time it was invoked. Thus, it doesn’t recalculate the result if the arguments are the same.
  • Selectors can be composed/chained together easily. This way, each selector stays small and focused on one task.

Here is a simple filteredTodos selector example to demonstrate how it works:

// selector.jsimport{ createSelector }from'reselect';consttodoSelector=state=> state.todo.todos;constsearchTermSelector=state=> state.todo.searchTerm;exportconst filteredTodos =createSelector([todoSelector, searchTermSelector],(todos, searchTerm)=>{return todos.filter(todo=> todo.title.match(newRegExp(searchTerm,'i')));});

With the help of this library, we can use the filteredTodos selectors to get all the todos if there’s no searchTerm set in the state, or a filtered list otherwise.

Also, we can get all the todos in a flat shape in conjunction with normalized data:

import{ denormalize }from'normalizer';import{ todo }from'../../schemas';constgetById=state=> state.todo.byId;constgetAllIds=state=> state.todo.all;exportconstmakeAllTodos=()=>createSelector([getAllIds, getById],(all, todos)=>denormalize(all,[todo],{ todos}),);

index.js

Here, we re-export all our actions, selectors and our reducer as a default export.

// index.jsexport*from'./actions';export*from'./selectors';export{default}from'./reducer';

Finally, our duck folder is ready!

This is the way we organize our React app structure to make the application maintainable when it scales. Additionally, here is another useful approach that is related to organizing the code of React component development. Let’s dive in.

Presentational and Container Components

One of the most common patterns to organize your React code is to split the project files into presentational and container components. Thus, containers provide the data needed to render the presentational components. It means that these components don’t have direct access to your Redux store or actions. Instead, they are passed down as props from their containers.

Inside the /route directory, the presentational components are suffixed with component, while containers are suffixed with container. The name of the component exported and its file name must be the same.

We prefer to set a .jsx extension to the presentational components while containers get a .js extension. The matter is that the container components mostly do not contain any React code:

src/| Component/|  ├── [name].component.jsx
|  ├── [name].container.js

As you can see, our best practices in structuring your React-Redux project files and code are simple-to-use and consequent. For sure, all of them are recommendations, not requirements. It means that you can find out another convenient way to keep your project structure comprehensive and make your application maintainable.

Final words

To conclude, when you start React application development, you can accelerate the setup process by using such solid ready-made solutions as CRA, Next.js, and Gatsby. These React development tools are a pretty good option if you want to avoid a time-consuming setup and get a fast and smooth launch. Surely, you can further configure your application structure the way you need and want.

At Codica, we have created our Best Practices on React-Redux project development that can help you understand your application architecture and build a well-structured code. There you can find sample code snippets and more detailed explanations.

Do you want to know more about front-end development with React? We recommend you to take a look at our blog article Vue vs React: Choosing the Best Tool for Your Project. In this article, you will find a detailed overview and comparison of these UI development tools within different programming aspects.

Article contents cta | Codica
Where Ideas Thrive
Bring your vision to life with a highly engaging and unique web application that your users love.
Learn more
Eugene Tech Lead & React/Next.js expert | Codica
Eugene
Tech Lead & React/Next.js expert
Eugene has vast experience building custom web products from scratch and supporting existing projects. He is fearless in solving challenging engineering issues.
Authors details
Rate this article!
Rate this article | CodicaRate this article full | CodicaRate this article | CodicaRate this article full | CodicaRate this article | CodicaRate this article full | CodicaRate this article | CodicaRate this article full | CodicaRate this article | CodicaRate this article full | Codica
(0 ratings, average: 0 out of 5)

Related posts

Stay up-to-date and never miss a resource

Subscribe to Codica newsletter

Latest posts