Let’s start with a bit of context here. Perhaps the changes in the world of the web are most visible when we talk about the frontend – the part of the website that is facing the users. Tim Berners-Lee made the first HTML specification public in 1991, and it consisted of text and under 20 tags. In 1994, we got cascading style sheets and the web started looking a little nicer. Legend has it that a new browser scripting language called Mocha was created in just 10 days – that was in 1995. Later, this language went through numerous changes and became what we know today as JavaScript – a powerful and fast language that, with the advent of Node.js, was able to conquer the servers, too.
Another important concept that has left a strong mark in the development of the frontend is the extensive use of Asynchronous JavaScript and XML (AJAX) – you might remember all those rounded corner web apps with vowel-based URLs. The technology of making asynchronous HTTP requests was known well before the arrival of Web 2.0 but was mostly underutilized. Libraries such as jQuery, but also Scriptaculous, MooTools, and more, began using AJAX and offering desktop-like interactivities in the browser.
One problem that quickly arose was the handling of data across shared views. Backbone, Knockout, and Ember were the most popular libraries that mitigated to solve that problem. In 2010, AngularJS came to light; this was a complex Model View Controller (MVC)-based framework with a very specific and prescribed way of doing things.
In May 2013, React was presented in the US and the web development world was able to witness numerous innovations – virtual DOM, one-way data flow, the Flux pattern, and more.
This is a bit of history to just try and provide some context and continuity because web development, like any other creative human activity, rarely moves in quantum leaps. Usually, it moves in steps that enable users to resolve the issues that they are facing in an, often, suboptimal way. It would be unfair not to mention Vue.js, which is an excellent choice for building frontends that also sports an entire ecosystem of libraries, and Svelte.js, which offers a radical shift in building UIs in the sense that the UI is compiled and the bundled size is significantly smaller.
Why use React?
As of 2022, interactive, attractive, fast, and intuitive UIs are a necessity for any public-facing web application. It is possible, though very difficult, to achieve most or every functionality that even a simple web is expected to provide using just plain JavaScript. FastAPI is more than capable of serving HTML (and static files, such as JavaScript or CSS) using any compatible templating engine (the most widely used in the Python world is probably Jinja2), but we and the users want more:
Figure 1.2 – The FARM stack
First of all, we want a streamlined and structured way of building UIs. React enables the developers to create dynamic applications in a much easier way by relying on JSX – a mix of JavaScript and XML that has an intuitive tag-based syntax and provides developers with a way to think of the application in terms of components that go on to form other, more complex, components, thus breaking the process of crafting complex user interfaces and interactions into smaller, more manageable steps.
The main benefits of using React as a frontend solution can be summarized as follows:
- Performance: By using the React virtual DOM, which operates in memory, React apps provide smooth and fast performance.
- Reusability: Since the app is built by using components that have their own properties and logic, we can write out components once and then reuse them as many times as needed, cutting down development time and complexity.
- Ease of use: This is always a bit subjective, but React is easy to get started. Advanced concepts and patterns require some level of proficiency, but even novice developers can reap immediate benefits just from the possibility of splitting the application frontend into components and then using them like LEGO bricks.
- SPAs or SSR: React and frameworks based on React empower us, the developers, to create Single-Page Applications that have a desktop-like look and feel but also server-side rendering that is beneficial for search engine optimization.
- React-based frameworks: Knowing our way around React enables us to benefit from some of today’s most powerful frontend web frameworks such as Next.js, static site generators (such as Gatsby.js), or exciting and promising newcomers (such as React Remix).
- Hooks system: In version 16.8, the React library introduced hooks that enable the developers to use and manipulate the state of the components, along with some other features of React without the need to use classes. This is a big change that tackles (successfully) different issues: it enables the reusability of stateful logic between components and simplifies the understanding and management of complex components.
The simplest React hook is probably the useState
hook – it enables us to have and maintain a stateful value (such as an object, array, or variable) throughout the life cycle of the component, without having to resort to old-school class-based components.
For instance, a very simple component that could be used for filtering search results when a user is trying to find the right car might contain the desired brand, model, and some production year range. This functionality would be a great candidate for a separate component – a search component that would need to maintain the state of different input controls – probably implemented as a series of dropdowns. Let’s just see the simplest possible version of this implementation. We will create a simple functional component with a single stateful string value – an HTML select element that will update the stateful variable named brand:
import { useState } from "react";
const Search = () => {
const [brand, setBrand] = useState("");
return (
<div>
<div>Selected brand: {brand}</div>
<select onChange={(ev) =>
setBrand(ev.target.value)}>
<option value="">All brands</option>
<option value="Fiat">Fiat</option>
<option value="Ford">Ford</option>
<option value="Renault">Renault</option>
<option value="Opel">Opel</option>
</select>
</div>
);
};
export default Search;
The bold line is where the hook magic happens, and it must be within the body of a function. The statement simply creates a new state variable, called brand, and provides us a setter function that can be used inside the component to set the desired value.
There are many hooks that solve different problems, and in this book, we will go over the fundamental ones. In this example, the state variable brand is available inside the component, and it could be tied to a query string that would enable the API to only return the results that conform to the filter defined by the state variable.
- Declarative views: In React, we do not have to worry about transitions or mutations of the DOM. React handles everything, and the only thing the developer has to do is to declare how the view looks and reacts.
- No templating language: React practically used JavaScript as a templating language (through JSX), so all you have to know in order to be able to use it effectively is some JavaScript, such as array manipulation and iteration.
- Rich ecosystem: There are numerous excellent libraries that complement React’s basic functionality – from routers to custom hooks, external library integrations, CSS framework adaptations, and more.
In this book, we will not dive deep into React. Why not? Well, I believe that the UI is as important as any other part of the app – if your app is not user-friendly or downright ugly, nobody will want to have anything to do with it, no matter how much value it brings. However, that is not the emphasis of this book. The idea is just to get the ball rolling and see how all the different parts connect and fit within the bigger picture. So, we will keep the frontend part to a minimum. Another reason to choose React is because of its great community, so you are bound to have to deal with it someday if you haven’t already, and to be quite honest, with the addition of React Hooks, at least for me, it has become very pleasant to work with. Hooks provide React with a new way of adding and sharing stateful logic across components and can even replace (in simpler cases) the need for Redux or other external state management libraries. We will make use of the Context API – a React feature that enables us to pass objects and functions down the component tree without the need of passing props through components that do not need it. Coupled with a hook – the useContext
hook – it provides a straightforward way of passing and maintaining stateful values in every part of the app. Just being able to create declarative reusable components and parametrize them into functions was what got me interested – treating visual and UI components like functions with a state if you will. Compared to other frameworks, React is small. It isn’t even considered a framework but a library – actually, a couple of libraries. Still, it is a mature product with over 10 years of development behind it, created for the needs of Facebook, and the biggest internet companies such as Uber, Twitter, and Airbnb use and rely upon it.
Like FastAPI, which is based on the newest and coolest Python features and, thus, makes maximum use of what the language has to offer, React uses (although it is not imperative) the newest features of functional JavaScript, ES6, and ES7, particularly when it comes to arrays. As someone said, working with React improves our understanding of JavaScript, and a similar thing could be said of FastAPI and modern Python.
The final piece of the puzzle will be the choice of a CSS library or framework. In 2022, there are dozens of CSS libraries that play nice with React, ranging from Bootstrap, Material UI, Bulma, and more. Many of these libraries merge with React to become meaningful frameworks of prebuilt customizable and parametrized components. We will use Tailwind CSS as it is simple to set up – all the cool kids are using it, and it is intuitive once you get the hang of it, but more on that later.
Keeping the React part to a bare minimum should allow you, the reader, to focus more on the true protagonists of the story – FastAPI and MongoDB and their dance – and easily replace the React part, should you wish to do so, with anything else that rocks your boat, be it Svelte.js, Vue.js, or vanilla handcrafted ECMAScript.
However, you should know that by embracing or, at the very least, learning the basics of React (and Hooks), you are embarking on a wonderful web development adventure that will enable you to use and understand many tools and frameworks built on top of React.
Arguably, Next.js is the feature-richest server-side rendering React framework that enables fast development, filesystem-based routing, and more. Gatsby, a React-based static site generator, is a great tool for crafting blazingly fast sites and, coupled with a headless CMS, enables us to create simple and streamlined workflows suited for non-technical staff. React-Remix seems to be an interesting project, with a lot of the new React features baked in. Lastly, learning one major frontend framework, be it React, Svelte, or Vue, enables you to switch to another much easier one – the problems they are trying to solve are pretty much the same, and the solutions and underlying philosophies have many things in common even if the implementations might differ drastically.