© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2021
E. ElromReact and Librarieshttps://doi.org/10.1007/978-1-4842-6696-0_1

1. Learn React Basic Concepts

Elad Elrom1  
(1)
Montvale, NJ, USA
 

This chapter serves as the ground school before we take off and start flying with React. We will create a minimalistic, stand-alone React application called “Hello World.” Then we will review how it works and see what’s happening under the hood. We will also learn about TypeScript and the starter template projects we can use to expediate development.

This chapter is the basis for understanding React, and although we are not building a flashy application here, the concepts that are covered are crucial. Feel free to return to the chapter again once you complete the book or even while reading later chapters if you need to reference some of the basic concepts.

Let’s get started!

Getting Started with React

In this section, we will create a minimalistic, stand-alone “Hello World” React example. We will be installing an integrated development environment (IDE), and we will cover crucial concepts such as JSX, the DOM, the React virtual DOM, Babel, and ES5/ES6.

First, though, we’ll talk about what React is and why to use it. Although it may be more gratifying to jump right in and start writing code, paying attention to the key concepts will help you understand React better. The entire book relies on you understanding the ideas in this section.

What Is React?

React (also known as ReactJS) is a JavaScript library developed by Facebook (https://github.com/facebook/react) to create user interfaces for the Web. React was invented by Jordan Walke, who was working at Facebook Ads at the time. It competes with other front-end development frameworks and libraries such as jQuery, Angular, Vue.js, Svelte, etc.

In its previous version, React 16.x, which was released in September 2017, the React team added more tools and development support and eliminated bugs. React 17 was released in October 2020.

Note

React 17 is a “stepping-stone” release, and the release is primarily focused on making it easier to upgrade React in future versions as well as improving compatibility with browsers. React team’s support shows that the library has great momentum and is not going away anytime soon.

Why React?

Did you know?

Installing an IDE

When working with code, it’s recommended that you use an IDE.

Why Do I Even Need an IDE?

You don’t “need” an IDE; you can always write your code with a text editor. However, an IDE helps write people code and increases productivity. This is done by providing common needed functionality for writing code, such as source code editor, build automation tools, and a debugger, as well as many other functionalities.

When it comes to IDEs, there are many to choose from. Some examples are Microsoft Visual Studio, IntelliJ IDEA, WebStorm, NetBeans, Eclipse, and Aptana Studio.

For this book, I selected Visual Studio Code (VS Code) since it’s a lightweight, free, cross-platform (Linux, macOS, Windows) editor that can be extended with plugins. You may be working for a company that will provide you with a specific IDE, or you may decide to invest and buy a top-rated IDE license. Most top IDEs mentioned offer similar functionalities, so it boils down to what you are used to using, licenses, etc.

Note

Choosing an IDE depends on many factors that I will not get into. You can install or use whatever IDE you are used to using; VS Code is just a suggestion.

You can also pick the Microsoft Visual Studio Express version instead of VS Code, which has reduced functionality compared to Microsoft Visual Studio.

How to Install VS Code?

To get started, go to the VS Code download page:
https://code.visualstudio.com/download
Choose your platform, and once the download is complete, open VS Code. You should see the Welcome page shown in Figure 1-1.
../images/503823_1_En_1_Chapter/503823_1_En_1_Fig1_HTML.jpg
Figure 1-1

Visual Studio Code Welcome page

Creating a Minimalistic Stand-Alone “Hello World” Program

It’s time to create our new “Hello World” app and run the project in our browser. To create a new file in VS Code, select New File. Then, paste in the following code and save the file anywhere you want:
<html>
  <head>
      <meta charSet="utf-8">
          <title>Hello world</title>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
          <script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
          <script src="https://unpkg.com/@babel/standalone/babel.min.js">
          </script>
  </head>
  <body>
  <div id="app"></div>
  <script type="text/babel">
      ReactDOM.render(
      <h1>Hello World</h1>,
      document.getElementById('app')
      );
  </script>
  </body>
</html>
You can download this code from the book’s GitHub location:
https://github.com/Apress/react-and-libraries/tree/master/01/index.html
Note

You can download all the code and exercises you see in this book from the book’s GitHub location (https://github.com/Apress/react-and-libraries). The files are organized by chapter.

Now that we have created the file, rename it to index.html and open it with your favorite browser (see Figure 1-1).
../images/503823_1_En_1_Chapter/503823_1_En_1_Fig2_HTML.jpg
Figure 1-2

React “Hello World” index.html app in the browser

Congratulations, you just created your first React application!

Now, let’s decode this example to understand what’s happening here.

Look at the ReactDOM.render function we created. It looks like this:
ReactDOM.render(
<h1>Hello World</h1>,
document.getElementById('app')
);

Although the code looks like HTML, it is not. It’s JavaScript eXtension (JSX) code.

Note

JSX is a React extension that uses JavaScript tags to mimic HTML code, so the code is similar to HTML but not the same.

What Is JSX, and Why Do We Need It?

To understand why React is using JSX instead of just HTML, we first need to talk about the Document Object Model (DOM). The quick answer is that React processes your JSX code in the background before committing these changes to the user’s browser to speed up how quickly the user’s page loads. Let’s dive deeper into that process.

Note

The DOM in HTML stands for Document Object Model. It is an in-memory representation of HTML and is tree-structured.

DOM

The Document Object Model is the API for HTML and even XML documents such as SVG images. The API describes the document by including interfaces that define the functionality of the HTML’s elements as well as any interfaces and types they rely on. The HTML document includes support and access to various things such as interacting with users such as event handlers, focus, copy and paste, etc.

The DOM document consists of a hierarchical tree of nodes (https://developer.mozilla.org/en-US/docs/Web/API/Node), and the node interface allows access not just to the document but to each element, as shown in Figure 1-3.
../images/503823_1_En_1_Chapter/503823_1_En_1_Fig3_HTML.jpg
Figure 1-3

A DOM document consists of a hierarchical tree

Use Chrome’s DevTools Console inspector (right-click a web page and select Inspect ➤ Console) and type this in the console:
window.document
Figure 1-4 shows the result. You can access the document hierarchical tree structure and the elements that make that tree.
../images/503823_1_En_1_Chapter/503823_1_En_1_Fig4_HTML.jpg
Figure 1-4

Chrome’s DevTools Console inspector showing the DOM document

DOM manipulation is the core of modern interactive web pages and can dynamically change the content of a web page. Technically speaking, this can be done using JavaScript with methods such as getElementById and getElementsByClassName as well as removeChild and getElementById("myElement").remove();. These APIs are exposed by the HTML DOM and intended to provide the ability to change code during runtime.

React determines what changes to make to the actual DOM based on the React element representation and do the changes in the background inside a virtual DOM. You can think of the React virtual DOM as a simulation.

Then it commits only needed changes to the actual user’s DOM (browser). The reason behind this process is to speed up performance.

It’s crucial that the actual DOM tree-structured manipulation be as quick as possible. For example, say we have a product page, and we want to update the first item of our product’s list. Most JavaScript frameworks would update the entire list just to update one item, which may contain hundreds of items.

Most modern web pages hold large DOM structures, and this behavior taxes the user too much, resulting in slower-loading HTML pages.

React Virtual DOM Under the Hood

The virtual DOM (VDOM) is a programming concept where an ideal, or virtual, representation of a UI is kept in memory and synced with the “real” DOM by a library such as ReactDOM. This process is called reconciliation. The React VDOM’s aim is to speed up this process.

React holds a copy of the HTML DOM (that’s the virtual DOM). Once a change is needed, React first makes the change to the virtual DOM, and it then syncs the actual HTML DOM, avoiding the need to update the entire HTML DOM, which speeds up the process.

For example, when we render a JSX element, every single virtual DOM object gets updated. This process of updating the entire virtual DOM instead of the actual HTML DOM is faster. In the reconciliation process, React needs to figure out which objects changed, and this process is called diffing. Then React updates only the objects in the real HTML DOM that need to be changed instead of the entire DOM tree.

In our code, the JSX code is wrapped inside a ReactDOM.render method . To further dig into the process behind the scenes and understand what’s happening under the hood, we also need to understand Babel and ES5/ES6.

Babel and ES5/ES6

The JSX code we write is just a terser way to write the React.createElement() function declaration. Every time a component uses the render function, it outputs a tree of React elements or the virtual representation of the HTML DOM elements that the component outputs.

ECMAScript version 5 (ES5) is plain old “regular JavaScript,” which was finalized in 2009. It is supported by all major browsers. ES6 is the next version; it was released in 2015, and it added syntactical and functional additions. ES6 is almost fully supported by all major browsers at the time of writing. In fact, the React team in version 17 made many changes to be more consistent and compatible with ES6.

We want to take advantage of ES6 functionality; however, at the same time, we want to be backward compatible with the old ES5 so we can be compatible in all versions of browsers. To do that, we use Babel.

Babel is the library that transpiles ES6 to ES5 (needed for browsers that don’t support ES6). The ReactDOM.render() function , as the name suggests, renders the DOM. The render function is expected to return a virtual DOM (representation of browser DOM elements).

Note

Starting from Babel 8, React gets a special function. The render method was changed to jsx.

Note that starting from Babel 8, React gets a special function called jsx to replace the render function. In Babel 8, it also automatically imports react (or other libraries that support the new API) when needed, so you don’t have to manually include them anymore if you write to Babel directly.

For example, look at this input:
function Foo() {
  return <div />;
}
Babel will turn the code into this:
import { jsx as _jsx } from "react/jsx-runtime";
function Foo() {
  return _jsx("div", ...);
}

Also starting from Babel 8, jsx will automatically be the default runtime. You can read more about these changes in my article on Medium: http://shorturl.at/bxPZ7.

Now that you understand what React is doing under the hood and Babel’s role, you can look back at our code example. Notice that we imported three libraries.
  • React version 17: We use React to define and create our elements, for example to use lifecycle hooks (more about hooks later in the book).

  • ReactDOM version 17: This is used for web applications (there is React Native for mobile devices). That’s why there is a split in the code between React and ReactDOM. ReactDOM is the glue between React and the DOM. It includes features that allow us to access the DOM, such as ReactDOM.findDOMNode() to find an element or ReactDOM.render() to mount our component.

  • Babel version 8: As we explained, Babel is the library that transpiles ES6 to ES5.

Now that we have looked at the React “Hello World” code, we understand why we imported these libraries and what’s happening under the hood. These key concepts are crucial to understanding React. Feel free to return to this chapter if you need a refresher.

In this section, we created a minimalistic stand-alone React application called “Hello World” and reviewed how to works. We installed the VS Code IDE and learned about crucial concepts such as JSX, DOM, the React virtual DOM, Babel, and ES5/ES6.

Getting Started with TypeScript

When it comes to writing React code, there are two options. You can write your code using JavaScript (JS) or TypeScript (TS). TypeScript is a transpiler, meaning ES6 doesn’t understand TS, but TS gets compiled down to standard JS, which can be done with Babel. We will configure our project to accept TS files as well as ES6 JS files in the next chapter.

Why Should You Integrate TypeScript into Your React Project?

Here are a few interesting facts:
  • Did you know that TypeScript is an open source programming language developed and maintained by Microsoft?

  • According to a 2020 StackFlow survey, the TypeScript programming language is second in popularity, surpassing Python!

  • The ReactJS framework is second at 35.9 percent and on its way to bypassing the “king” jQuery.

  • At the same time, 32.9 percent of respondents said that they actually dreaded TypeScript.

The question is, why TypeScript is so popular?

TypeScript vs. JavaScript: What’s the Big Deal?

JavaScript is a scripting language, while TypeScript (TS) is a full-blown programming language. TS, as the name suggests, is all about having more types. TS is easier to debug and test than JS, and TS prevents potential problems by describing what to expect (you will see this in action when we test our components later in this book). Having a full-blown object-oriented programming (OOP) language and modules brings JS to an enterprise level and increases code quality.

These are the advantages of TypeScript over JavaScript:
  • TypeScript is an OOP language; JavaScript is a scripting language.

  • TypeScript uses static typing following the ECMAScript specification.

  • TypeScript support modules.

Note

A type system associates a type to each value. By examining the flow of these values, it ensures there are no type errors.

Static typing means that types are checked before runtime (allowing you to track bugs before runtime). JS includes only the following eight dynamic (at runtime) types: BigInt, Boolean, Integer, Null, Number, String, Symbol, Object (objects, functions, and arrays), and Undefined.

Note

All these types are called primitive types, except for Object, which is a nonprimitive type. TS adds static types to JavaScript by setting a compiler to type-checking the source code to turn it into dynamic code.

React and TypeScript work nicely together, and by using TypeScript and describing the types your code quality improves the code quality of your app using OOP best practices, it’s worth the learning curve.

In the next chapter, we will create a startup project with TypeScript; however, you can start experimenting with TypeScript right now and learn the basics.

This step gives you a good overview of the types of TS and how you can harness the power of TS in your code.

TS is at version 4. To play around with coding TS, you can run actual TS code in the TS Playground, available at https://tc39.github.io/ecma262/#sec-ecmascript-language-types, as shown in Figure 1-5.
../images/503823_1_En_1_Chapter/503823_1_En_1_Fig5_HTML.jpg
Figure 1-5

TS Playground

The left side of the Playground is TS, and the right side is the same code compiled into JS. Next, open the JavaScript Console and hit Run to see the code running.

The Playground site has plenty of examples that can help you better understand TS. I recommend exploring the examples.

Notice the example uses “strict,” and in the Config menu item, you can set the compiler options from the Config link. The different compiler options are at https://www.typescriptlang.org/docs/handbook/compiler-options.html.

It may be antagonizing writing your code with errors popping up left and right, but it will avoid issues later when the compiler can’t figure out the types. I mentioned that TS is OOP and follows the ECMAScript specification; however, the specification is a living thing and changes often, so you can specify the ECMAScript (ES) target. See Figure 1-6.
../images/503823_1_En_1_Chapter/503823_1_En_1_Fig6_HTML.jpg
Figure 1-6

Specifying the ECMAScript (ES) target in TS Playground

TypeScript Cheat Sheet

A great place to start working with TypeScript is to understand the power of TS by looking at the different types available. My programming style is to follow the function naming conventions of coding like Shakespeare and having the names of the method self-explain themselves.

To try TypeScript, paste the TypeScript cheat sheet code shown here into the TS Playground at https://www.typescriptlang.org/play/. Then you can follow along and look at the results of the JS compiler and run the code. As you can see, I split my examples into primitive types and nonprimitive types.

// primitive types
// The most basic datatype - true/false switch
const flag1: Boolean = true;
// inferred-type
const flag2 = true;
// Be a programming god - create your own type
type Year = number;
const year: Year = 2020;
// Undefined and null not included in types like js, to
// get a null you will set it as either null or number
let willSetValueLater: null | number = null;
console.log('willSetValueLater: ' + willSetValueLater);
willSetValueLater = 2020;
console.log('willSetValueLater: ' + willSetValueLater);
// none-primitive
// Arrays
let arrayNumber: number[] = [];
let myCastTypeArrayNumber: Array<number> = [];
myCastTypeArrayNumber.push(123);
console.log('myCastTypeArrayNumber: ' + JSON.stringify(myCastTypeArrayNumber));
// Tuples (two values)
let longlatSimple: [number, number] = [51.5074, 0.1278];
let longlatInferredType = [51.5074, 0.1278];
// Enums design pattern
enum ChildrenEnum {JOHN = 'John', JANE = 'Jane', MARY = 'Mary'}
let john: ChildrenEnum = ChildrenEnum.JOHN;
console.log('What is JOHN enum? ' + john);
// Maps
// inferred type: Map<string, string>
const myLongLatMapWithInferredType = new Map([
  ['London', '51.5074'],
  ['London', '0.1278'],
]);
// interfaces
// Typing objects-as-records via interfaces
interface longlat {
  long: number;
  lat: number;
}
function longlatToString(longlat: longlat) {
  return `${longlat.long}, ${longlat.lat}`;
}
// Object literal (anonymous interfaces) inline:
function longlatToStringWithAnonymousInterfaces(longlat: {
  long: number;
  lat: number;
}) {
  return `${longlat.long}, ${longlat.lat}`;
}
// Place optional params (phone) and method in interface
interface Client {
    name: string;
    email: string;
    phone?: string ;
    longlatToString(longlat: longlat): string;
}
// Factory design pattern made easy using type cast
interface resultsWithUnkownTypeCast<SomeType> {
  result: SomeType;
}
type numberResult = resultsWithUnkownTypeCast<number>;
type arrayResult = resultsWithUnkownTypeCast<[]>;
// functions
// Simple function
const turnStringToNumber: (str: String) => Number =
    (str: String) => Number(str);
// %inferred-type: (num: number) => string
const turnStringToNumberMinimalist = (str: String) => Number(str);
console.log('turnStringToNumber: ' + turnStringToNumber('001'));
console.log('turnStringToNumberMinimalist: ' + turnStringToNumberMinimalist('002'));
function functionWithExplicitReturn(): void { return undefined }
function functionWithImplicitReturn(): void { }
// Simple functions with callbacks
function simpleFunctionWithCallback(callback: (str: string) => void ) {
  return callback('done something successfully');
}
simpleFunctionWithCallback(function (str: string): void {
    console.log(str);
});
// Never callback  - not placing never is inferred as never
function neverCallbackFunction(callback: (str: string) => never ) {
  return callback('fail');
}
// neverCallbackFunction(function(message: string): never {
//     throw new Error(message);
// });
// Complex Callback and specifiy result types
function complexCallbackWithResultType(callback: () => string): string {
  return callback();
}
console.log('doSomethingAndLetMeKnow: ' + (complexCallbackWithResultType(String), 'Done it!'));
// Function with optional params using '?'
function functionWithOptionalCallbackParams(callback?: (str: String) => string) {
  if (callback === undefined) {
    callback = String;
  }
  return callback('sucess');
}
// Function with setting the type with default values
function createLonglatWithDefaultValues(long:number = 0, lat:number = 0): [number, number] {
  return [long, lat];
}
console.log('createLonglatWithDefaultValues: ' + createLonglatWithDefaultValues(51.5074, 0.1278))
console.log('createLonglatWithDefaultValues: ' + createLonglatWithDefaultValues())
// function with rest parameters
// A rest parameter declared by prefixing an identifier with three dots (...)
function functionWithRestParams(...names: string[]): string {
  return names.join(', ');
}
console.log(functionWithRestParams('John', 'Jane', 'Mary'));
// Function with potential two params types
function isNumber(numOrStr: number|string): Boolean {
  if (typeof numOrStr === 'string') {
      return false;
  } else if (typeof numOrStr === 'number') {
      return true;
  } else {
    throw new Error('Not sure the type');
  }
}
console.log('isNumber: ' + isNumber('123'));
You can download the complete code from here:
https://github.com/Apress/react-and-libraries/tree/master/01/TS-getting-started.ts
If you need more explanation, see the official TS basic types handbook here:
https://www.typescriptlang.org/docs/handbook/basic-types.html
The JS compiler that turns the code from TS to JS and the console results will help you understand these examples. See Figure 1-7.
../images/503823_1_En_1_Chapter/503823_1_En_1_Fig7_HTML.jpg
Figure 1-7

TypeScript Playground examples

React Template Starter Project Options

When it comes to writing React applications, you have a few options. You can just write the entire code yourself, as we did for our “Hello World” example, and then add libraries to help you take care of tasks of packaging your code and getting it ready for production. Another option is to use a starter template project that already takes care of the scaffolding and configurations and includes libraries to help you get the job done quickly with just writing your code.

As you have seen, the VDOM process happens behind the scenes, and we don’t need to refresh the page when there is a page change.

In fact, the most popular template for creating a React app is the Create-React-App (CRA) project (https://github.com/facebook/create-react-app). The project was created by the Facebook team with close to 84,000 stars on GitHub.

CRA is based on a single-page application (SPA), which is great because you don’t get a page refresh, and the experience feels like you are inside of a mobile app.

The pages are meant to be rendered on the client side. This is great for small to medium-sized projects.

The other option is server-side rendering (SSR). SSR renders the page on the server so the client (browser) will display the app without doing any work. It’s good for certain use cases (usually large apps), where there is much going on and the user experience would be sluggish if the rendering happened on the client side.

CRA doesn’t support SSR out of the gate. There are ways to configure and get CRA to work as SSR, but that may be too complex to some developers and involve maintaining configuration on your own, so it may not be worth the effort.

If you’re building something bigger that needs SSR, it’s better to just work with a different React library that is already configured out of the box with SSR such as the Next.js framework, Razzle, or Gatsby (include a prerender website into HTML at build time).

Note

If you want to do server rendering with React and Node.js, check out Next.js, Razzle, or Gatsby. Create React App is agnostic of the backend and only produces static HTML/JS/CSS bundles. See https://github.com/facebook/create-react-app.

With that being said, with CRA we can do a prerender, which is the closest you can get to SSR, as you will see in the last chapter of this book when we optimize our React app.

In this book’s examples, we will be using CRA; however, with a solid understanding of this book, you can easily migrate to any template library that uses React.

Summary

In this chapter, we created a minimalistic stand-alone React application called “Hello World” and explored how it worked. We installed the VS Code IDE and learned about crucial concepts such as JSX, DOM, React’s virtual DOM, and Babel, as well as ES5/ES, SPA, SSR and TypeScript.

In the next chapter, we will learn more about the CRA project and set up our starter project and development environment with essential libraries.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.36.10