JavaScript For React-Rel1
JavaScript For React-Rel1
Intermediate JavaScript
to master before learning React
JS JS JS JS
JS JS
JS
Satoshi Yoshida
Simona Yoshida
2
All rights reserved. No part of this book may be reproduced or used in any manner without
the written permission of the copyright owner except for the use of quotations in a book
review. However, all code examples in the CodeSandbox created for this book are free to
fork.
(Aristotle 384-322BC)
4
One of the advantages of React is its flexibility. React could be used for client-side
rendering or server-side rendering. Although React is a UI library, many developers
consider it a framework because React imposes the component-based architecture that
developers must adopt. React has a considerable architectural impact on every aspect of
an app that would use them.
Unlike Angular, React is not a complete framework, and advanced features require
additional libraries for state management, routing, and interaction with an API. This
makes the basic core React simple and the learning curve not so steep. However,
depending on the path you take with additional libraries, the learning curve can be very
steep.
This free tutorial is extracted from chapters 1 & 2 of the book “React Hooks Redux in 48
hours”, released from Amazon.com in July 2021. Chapter 1 is the JavaScript React
ecosystem overview. You could skip this chapter if you are busy.
5
• Non-Web software engineers or system architects know at least one of the high-
level languages.
6
TABLE OF CONTENTS
1. OVERVIEW ............................................................................................................... 11
Flux ............................................................................................................................. 27
Redux .......................................................................................................................... 28
Redux-Thunk .............................................................................................................. 30
Redux-Saga ................................................................................................................. 31
Recoil .......................................................................................................................... 32
Concurrency in rendering............................................................................................ 33
CodeSandbox .............................................................................................................. 42
Babel ........................................................................................................................... 44
Webpack...................................................................................................................... 45
Methods ....................................................................................................................... 64
Arguments ................................................................................................................... 65
Constructors ................................................................................................................ 71
Bind ............................................................................................................................. 75
9
Memoization ............................................................................................................... 77
Closure ........................................................................................................................ 94
Subclassing................................................................................................................ 105
Promise...................................................................................................................... 109
async.......................................................................................................................... 118
1. OVERVIEW
(one hour reading)
1.1 JavaScript
As React is not a full-fledged framework, it is relatively easy to learn. Instead of working
in a preset pattern, a developer can add any library according to their preferences. For
example, Redux is widely used by developers as state management.
JavaScript ecosystems come and go. But learning React also means you will have to learn
JavaScript. Being a react developer will make you a good JavaScript developer
automatically. Even if React became obsolete in the future, your JavaScript skills are still
relevant and re-usable.
JavaScript is a dynamically typed programming language, meaning that the variables can
be reassigned with a value of a different data type after initialization. JavaScript runs
natively in the browser and is quite a strange language compared to current mainstream
languages.
• Metaprogramming - ES6 supports the Proxy and Reflect objects, which allow
you to intercept and define custom behavior for fundamental language operations.
Metaprogramming is useful when developing a new language based on JavaScript.
14
Recently there has been a growing trend toward Functional Programming. With libraries
like React/Redux, you will achieve clean software by using immutable data structures.
Immutability is a core concept of Functional Programming. Overall, there are many
advantages to Functional Programming in JavaScript. Douglas Crockford says that
JavaScript is “Lisp in C’s Clothing.” In fact, JavaScript may be a bit cheaply looking
Functional Programming language. React Hooks and Redux are influenced by Functional
Programming. The problem is that many programmers who come from an object-oriented
background seem to have difficulties in adopting Functional Programming principles in
the first place.
React relies heavily on JavaScript. It takes a component’s state, JavaScript objects, and
using JavaScript functions to manipulate the state. The page is then rendered to reflect
those changes. The fact that React relies heavily on plain JavaScript can be good and bad,
depending on how strong your JavaScript skills are. The closure, classes, event handling,
importing, exporting, callback functions, higher-order functions, curry, etc., are used in
React. If you don’t know JavaScript, you will get stuck and return to JavaScript tutorials
many times. In the end, you might end up wasting your time.
15
The following diagram shows the client-side architecture. For the browser, JavaScript is
like a machine code that runs under the CPU.
User Interface
Rendering Engine
Database UI Backend
16
• User interface (UI): It includes the address bar, the back, forward buttons, text input,
radio button, submit button, etc. It is every part of the browser display except for the
window where you see the web page itself.
• Browser engine: The interactions between the user interface and the rendering
engine.
• Rendering engine: It is for displaying the web page. The rendering engine parses the
HTML and the CSS and displays the parsed content on the screen. The rendering
engine receives the contents of the requested document from the networking layer.
• JavaScript engine: This is where the JavaScript gets executed. Modern browsers
don’t use a conventional interpreter. For example, Google Chrome’s V8 compiles
JavaScript directly to CPU machine code using just-in-time (JIT) compilation before
executing it. The compiled code is additionally optimized dynamically at runtime.
• Networking: These are network protocols such as XHR requests, which are a
platform-independent interface.
• Local Data storage: The apps may need to store all data locally. The supported types
of storage mechanisms include localStorage, indexDB, WebSQL, and FileSystem.
17
ECMAScript (ES2016, ES2017, ES2018, ES2019, and ES2020) has been updated every
year. The good news is that no large-scale additions have been made at present because the
change from ES5 to ES6 was too drastic. It has been released every year to improve it
gradually. This makes it very easy for users to follow the new specifications.
ECMAScript does not have a static type, but the type checking is feasible using a superset
of ECMAScript called TypeScript that adds a type definition to ECMAScript. The main
benefit of TypeScript is that a compiler detects descriptive errors in case of type violations.
However, if you are new to JavaScript, we recommend learning the native JavaScript first
to understand JavaScript’s runtime behaviors. Since TypeScript is compiled to JavaScript,
you still have to learn how JavaScript works anyway.
Much like Java/C#, TypeScript emphasizes a class-based type system, which promotes
creating classes with methods that you need to instantiate.
React also have their own way of enforcing type (prop-types to ensure correct types at
component interfaces), unit testing for components and logic, so TypeScript is not
mandatory. Typescript comes in handy when you develop large-scale apps.
18
Component-Based
Components are the building blocks of any React application, and a single app usually
consists of multiple components. React splits the UI into independent, reusable parts that
can process separately. You can build encapsulated components that manage their own
state, then compose them to make complex UIs.
Virtual DOM
The virtual DOM stores a representation of the UI in memory and is synchronized with
the actual DOM. The virtual DOM compares the components’ previous states and updates
only the Real DOM items that were changed, instead of updating all of the components
again, as conventional web applications. It makes web applications faster.
React Elements
The browser DOM is made up of DOM elements. Similarly, the React DOM consists of
React elements. They may look the same, but they are quite different in concept. React
element is a representation of a DOM element in the virtual DOM and is an
instruction for how real DOM should be created.
We call this a “root” DOM node because everything inside will be managed by React
DOM. Applications built with React usually have a single root DOM node. If you are
integrating React into an existing app, you may have as many isolated root DOM nodes as
you like.
To render a React element into a root DOM node, two parameters are required in method
ReactDOM.render([what], [where]). A React element using JSX syntax is like below. It
looks just like HTML, but there is more than that:
React.createElement is a method included in the React library. You can build React apps
without using JSX. However, using JSX is strongly recommended for readability and
maintenance.
An element is a plain object describing a component instance or DOM node and its
desired properties. It contains only information about the component type, its properties,
and any child elements inside it. A React element is not an actual instance. It is more like
a way to instruct React what you want to see on the screen. You can’t call any methods on
the element.
20
React Components
A component is a function or a class that optionally accepts input and returns a
React element. A component is an abstraction over an element. They may carry some
internal state, and they may behave differently depending on the props they receive.
When asked to render, components return elements.
Conceptually, components are like JavaScript functions. They accept arbitrary inputs and
return React elements describing what should appear on the screen. For example,
Facebook has thousands of pieces of components interfaced together when you view their
web application. The component-based architecture allows you to think of each block in
isolation. Each component can update everything in its scope without being concerned
about how it affects other components.
React components are reusable and can be injected into interfaces if necessary. For a
better understanding, consider the entire UI as a tree-like structure below. Here the starting
component becomes the root, and each of the independent pieces becomes branches,
which can be further divided into sub-branches.
React's mechanisms for communicating among components are simple and effective.
Props allow data to flow down the component hierarchy from parent to child. When a
child wants to talk back up to a parent, a callback function is passed through props.
x
A
A
D
B D
B
C E F C E F
21
Virtual DOM
In React, instead of directly accessing the real DOM (Document Object Model), it
manipulates the virtual DOM. The virtual DOM is a node tree listing of components
created in memory. It is a memory area corresponding to the real DOM. The render( )
method in React creates the Virtual DOM.
Each time the underlying data changes, new Virtual DOM is created, comparing the
previous virtual DOM and the current virtual DOM, and only the changes are updated in
real DOM. ReactDOM.render( ) method updates DOM elements that have changed.
In React, there are various ways we can pass data to/from components:
1. Render Props
2. Context API
3. React Hooks (useContext API)
4. React-Redux/Redux
5. Other state management libraries (i.e., XState, MobX)
In the typical React dataflow, props are the only way that parent components interact with
their children. To modify a child, you re-render it with new props.
23
In a React component, state holds data that can be rendered to the user. State is a
structure that keeps track of how data changes over time in your application. Props
stand for properties and are being used for passing data from one component to
another.
Data is updated and manipulated by using props and state. Props and state determine how
a component renders and how it behaves. If components are plain JavaScript functions,
then props would be the function input. A component accepts an input (what we call
props), processes it, and then renders some JSX code.
In principle, props should be immutable data and top-down direction. This means that the
parent component can pass on whatever data it needs to its child component as props, but
the child component cannot modify its props.
24
On the other hand, state is an object owned by the component where it is declared. Unlike
props, state is local to the component and can only be initialized and updated within the
component. When the state object changes, the component re-render. When state is
passed out of the current scope, it is referred to as props. The state of the parent
component usually ends up being props of the child component.
Global state in React means our state is accessible by every element/component of the
application. But the important fact is that it could pollute the whole app since every
component can access and update it.
25
Functional Components
A component is a JavaScript ES6 class or function that optionally accepts inputs (props)
and returns a React element that describes how a section of the UI should appear.
Functional components are just JavaScript functions. They take in an optional input
(props) and return some JSX directly for rendering. The Functional component does not
support state.
Component
const Button = (props)=> {
return (
props <button>
DOM
)}
ES6 class components have more features. The primary reason to choose Class-based
components over Functional components is that they can have state. Class components
can be used without state too. Class components implement a render function to return
some JSX.
Component
class App extends ABC {
props State={……..} DOM
return ()
<div> ………….</div>
}}
26
Hooks is a new addition in React 16.8 that lets you use state and other React features in
the functional component without writing a class component. Hooks brings all previously
available features in class components into functional components.
Component
const Button = ()=> {
const [x, y] = useState(z);
props return (
DOM
<button>
)}
Flux
After having learned the complexity of the MVC (Model View Controller) architecture,
the Facebook team developed Flux as an alternative to MVC architecture. Flux follows
unidirectional data flow, which supports a composable view of React's components. The
Flux architecture is based on the following blocks:
• Action: Every change to state starts with an action, which is a JavaScript object
describing an event in your application. The actions are typically generated by
user interaction or by a server event, such as an HTTP response.
• Dispatcher: coordinates actions and updates the store.
• Store: manages the application's state and decides how the state will be updated.
An application has multiple state portions, and each of them is dependent on the
numerous stores of the application.
• View: the user interface component, which is responsible for rendering the user
interface and handling the user interaction.
ACTION
VIEW/UI
28
Redux
Redux was created by Dan Abramov and Andrew Clark in 2015. Redux is a library based
on Flux architecture. The major difference between Flux and Redux is that Flux can
include multiple Stores per app, but Redux includes a single Store per app.
Redux is a predictable state management library to store your app state in one place and
manipulate it from anywhere in your app. It helps us write applications that behave
consistently, run in different environments (client, server, and native), build more
maintainable code, and much easier track down the root cause when something goes
wrong. Redux architecture is based on the following components:
• Store: A store is a state container that stores the whole state of the apps in an
immutable object tree. Whenever the store is updated, it will update the React
components which are subscribed to it. Redux enforces a single global store.
• View: The user interface component, which is responsible for rendering the user
interface and for handling the user interaction. The views emit actions that describe
what happened. Your app reads the state from the store.
29
As the data flow in redux is predefined, you have to stick with it. In smaller applications,
the amount of boilerplate seems to be excessive. On the other hand, in larger applications,
the predefined factory-like data flow helps us. With Redux, you have a centralized
location where your application's global state is stored, and the state can only be changed
by dispatching actions. When an action is dispatched, the state is updated, and components
rerender accordingly. It is easy to reason about and to keep track.
You may not always need Redux for every app. If your app consists of a single view, does
not save or load state, and has no complicated asynchronous I/O, you may not find a good
reason to add the boilerplate of Redux. Some people think that Hooks (useContext and
useReducer) will replace Redux. But Redux is application-level global state management.
Hooks are mostly for managing state in components themselves, so usages are completely
different. As the complexity of an app increases, more data needs to be managed across the
app. In many cases, the state management with one global state container can simplify
your application.
According to the “State of Frontend 2020" survey, 48% of React apps use Redux. If you
are working on your own project, Redux is not mandatory for simple react applications.
However, if you are working with other React developers or preparing for a job interview,
you might as well know Redux, even if you decide not to use it.
30
Redux-Thunk
By default, actions in Redux are dispatched synchronously, which is a problem for any
app that needs to communicate with an external API or perform side effects. Redux-Thunk
provides a good way of solving the complexity of asynchronous nature in JavaScript via
dispatch chaining.
In Redux, actions are defined with simple objects or action creator functions that return an
object. Redux-Thunk lets us call action creators that return a callback function
instead of an action object. The Thunk function receives the dispatch method, which is
then used to dispatch regular synchronous actions inside the body of the function once the
asynchronous operations have been completed.
31
Redux-Saga
Redux-Saga is a library bringing the concept of "task" to Redux. If you have experience in
embedded software with an RTOS environment, it is a relatively straightforward concept.
Redux-Saga acts as a middleware that allows developers to separate any business logic,
Ajax, data manipulation, or any other asynchronous operations, which may not seem
appropriate to processing in reducers directly.
In comparison to Thunk, the benefit of Saga is that we can avoid callback hell. We could
avoid passing in functions and calling them inside. Additionally, we can test our
asynchronous data flow more easily. Saga can be used to set up complex control flows
within our state management system. Saga is suited for complex/large-size applications.
The downside is that a bit steep learning curve is expected.
32
Recoil
Recoil is an experimental state management library introduced by the Facebook team. Just
like Redux, Recoil is not an official state management library for React.
Recoil provides several capabilities that are difficult to achieve with React alone. Recoil
lets us create a data-flow graph that flows from atoms (shared state) through selectors
(pure functions) and down into our React components. Atoms are pieces of React state
that can be subscribed to by any component inside the root component. Selectors are pure
functions that can receive atoms and selectors and return derived state (computed values
or transformation of state). The Recoil hooks are designed to be easily incorporated into
custom hooks.
The concept of atoms is to isolate the state in small pieces, making it very flexible. Using
selectors, we can easily combine pieces of state and move between being synchronous and
asynchronous without modifying the components.
In a nutshell, Recoil is like a global version of React’s useState hook. It also supports
Concurrent Mode, which is still in the works at the time of writing.
33
Concurrency in rendering
React, and its libraries are written in JavaScript that runs on the main thread. The main
thread also runs DOM updates, browser paints, etc. JavaScript runs on a single main
thread, which blocks the react rendering and updating.
In Concurrent Mode, React can work on several state updates concurrently. It means that
React can render multiple trees simultaneously, interrupt, delay, or dismiss an ongoing
render and defer state updates.
• For CPU-bound updates (such as creating DOM nodes and running component
code), concurrency means that a more urgent update can “interrupt” rendering that
has already started.
• For IO-bound updates (such as fetching code or data from the network),
concurrency means that React can start rendering in memory even before all the
data arrives and skip showing empty loading states.
Note: The Concurrent mode is still in the experimental stage at the time of writing in
March 2021.
34
loading
3 Create HTML files
If necessary
- ロ
4. Send response
5. Receive Response
Viewable
6. Render the page
9. Create JS files
If necessary
10. Send response
11. Receive Response
Conventional Server Side Rendering has the following advantages and disadvantages.
PROS
• Advantage in SEO (Search Engine Optimization).
• Initial load duration is shorter.
CONS
• Second and further page load takes time.
• Difficult to handle heavy user interactions.
• Partial real-time updates can be difficult.
• Synchronous rendering, which blocks other processes.
• In the case of a large number of requests, performance will decrease due to the data
communication delay and data traffic.
• Achieving natural UX may be difficult.
• Much longer time to develop mobile applications.
36
A Single-Page Application (SPA) is an app that runs under the browser and does not
require page reloading during use. For instance, Gmail, Google Maps are typical SPAs.
SPA is just one web page and then loads all other content using JavaScript. SPA can
serve an outstanding UX (User Experience) since there are no entire page reloads, no extra
waiting period. Rather than re-loading each page entirely, a SPA application loads content
dynamically. The fundamental code (HTML, CSS, and JavaScript) of the website is
loaded just once.
In the client-side rendering, JavaScript renders the content in the browser. Instead of
having the content inside the HTML file, we are getting an HTML document with a
JavaScript file that will render the rest of the site using the browser. When we interact
with the application, JavaScript intercepts the browser events. Instead of making a new
request to the server for a new document, the client requests JSON or process on the
server. Since the page that the user sees is not entirely updated, the users feel more like a
desktop application.
37
PROS
• Handle heavy user interactions.
• Once the initial load is done, the second and further page loading duration is short.
• Partial real-time updates are possible.
• Asynchronous rendering that does not block other processes.
• Less server-client traffic.
• Excellent UX
• Mobile-friendliness
• Easy to transform into Progressive Web Apps with local caching and offline mode.
CONS
• Disadvantage in SEO (Search Engine Optimization).
• Long initial load duration.
• Performance issues on old mobile devices/slow networks.
38
Server-Side Rendering (SSR) is not mandatory to build a React app. React is known as a
client-side JavaScript library, but React supports server-side rendering as well. In the
conventional SSR, every page is rendered and loaded from the server. However, with the
introduction of Universal React SSR, things are different.
A typical pattern in Universal React SSR is that server renders a page and then
(re)hydrates client-side DOM through a serialized version of a UI's dependencies. React
SSR allows you to pre-render the initial state of your React components server-side. This
speeds up initial page loads as users do not need to wait for all the JavaScript to load
before seeing the web page.
Since the server renders the initial page and the subsequent pages load directly from the
client, you have the best of both worlds — the power of the initial server-side content and
the speedy subsequent loads, which requests just the content needed for subsequent
requests. Your application becomes more visible for Google crawlers to find your page in
addition to the above benefit.
The downside is that implementation can be very complicated. In many cases, you might
end up creating systems having the worst of Server Side Rendering and Client-Side
Rendering. Therefore, using a framework like Next.js is highly recommended. Next.js for
React, Nuxt.js for Vue, Angular Universal for Angular are frameworks using Universal
Rendering.
39
JAMstack (JavaScript, APIs, and Markup stack) is the revolutionary architecture designed
to make the web faster, more secure, and easier to scale. Its deployment doesn’t run on a
traditional setup of origin servers. Instead, automated deployments are used to push sites
directly to CDNs (Content Delivery Network).
With various tools and workflows, pre-rendered content is served to a CDN and made
dynamic pages through APIs and serverless functions. Technologies in the JAMstack
include JavaScript frameworks, Static Site Generators, Headless CMSs, and CDNs.
The static site generators generate the content during build time. Then, once loaded, React
takes over, and you have a single-page application. Static rendering achieves a
consistently fast Time-to-First-Byte since the HTML for a page doesn’t have to be
generated on the fly. With HTML responses being generated in advance, static renders can
be deployed to multiple CDNs.
Gatsby and Next.js (version 9.3 onwards) are the popular frameworks supporting the
Static Site Generator.
React Native
The working principles of React Native are identical to React. The significant difference
is that React Native does not manipulate the Browser DOM. React Native invokes Object-
C APIs to render to iOS components or Java APIs to render to Android components
instead of rendering to the Browser DOM. This is possible because of the bridge, which
provides React with an interface into the host platform´s native UI elements.
React components return markup from their render function, which describes how they
should look. With React for the Web, this translates directly to the Browser DOM. As for
React Native, this markup is translated to suit the host platform, so a <View> becomes an
iOS-specific UI component or Android-specific UI component. React components wrap
existing native code and interact with native APIs via React’s declarative UI and
JavaScript.
If you are comfortable with Web-based React, learning React Native is easy. Thousands
of apps are using React Native.
PWA is delivered through a browser. It behaves like a native application, offering gestures
and app-like style, but based on the Web. PWA is responsive and can be browsed on any
mobile device, desktop, or tablet. Twitter, Uber, Instagram, Financial Times, Forbes, and
many organizations use the PWAs.
• Service worker: A service worker is a JavaScript file that runs in the background,
separately from the main browser thread, intercepting network requests, caching or
retrieving resources from the cache, and delivering push messages.
• JSON manifest file: The JSON file contains information on how your PWA
should appear and function.
• HTTPS: PWAs only work on secured connections.
If your goal is to target mobile devices (Android and iOS) only via the app store, use
React Native. If you want to reach a broader range of users and devices via the browser,
go with PWAs. If you wish for the lowest-cost option for your development team, then
PWAs wins.
42
CodeSandbox
CodeSandbox is a free Online editor/playground/Cloud IDE tool for JavaScript
framework/library. CodeSandbox allows developers to focus on writing code while it
handles all the necessary background processes and configurations. CodeSandbox focuses
on building and sharing code demos that contain back-end components. The editor is
optimized to analyze npm (Node Package Manager) dependencies, show custom error
messages, and also make projects searchable by npm dependency.
The following is an example of the “Hello CodeSandbox” with React. Please play around
by modifying files - index.html, styles.css, index.js, and App.js.
reload
Test mode
Browser mode
Babel
Babel is a free and open-source JavaScript transpiler, mainly used to convert ES6+, JSX,
or TypeScript code into a backward-compatible version of JavaScript that can be run by
older JavaScript engines. You don’t have to install Babel manually when using
CodeSandbox.
45
Webpack
Webpack is an open-source module bundler primarily for JavaScript, but it can transform
front-end assets like HTML, CSS, and images if the corresponding loaders are included.
Webpack takes modules with dependencies and generates static assets representing those
modules. You don’t have to install Webpack manually when using CodeSandbox.
46
2. INTERMEDIATE JAVASCRIPT
(6 hours reading and exercise)
(Voltaire 1694-1778)
This chapter is not a complete tutorial on all features of the JavaScript language. Instead,
it will outline a set of fundamental principal that require for understanding React
ecosystems.
JavaScript is not a pleasant language by any standard. The good news is that you don’t
have to master the whole ECMAScript spec before learning React. You might as well
focus on learning the minimum things, which are covered in this chapter.
If you don’t know JavaScript at all, reading the following JavaScript tutorial is
recommended.
https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics
We would also recommend “YOU DON´T KNOW JS series Up & Going ” O’Reilly
(Kyle Simpson). A free PDF version may be available depending on your area.
If you are comfortable with advanced JavaScript such as Closure, Currying, Higher-Order
function, and ES6, you might as well skip this chapter.
47
String A character or sequence of characters placed inside var myString = ‘hello world’
quote marks (‘ ’) or (“ “)
Number Any integer or floating point numeric value. var myNumber = 12345
Symbol A symbol is a unique and immutable data type that var mySymbol1 = Symbol(sym)
(ES6) is often used to identify object properties. Every var mySymbol2 = Symbol(sym)
symbol value returned from Symbol( ) is unique. A
symbol value may be used as an identifier for object
properties.
In the primitive data type, the values themselves are stored in memory directly.
48
Object An unordered list of properties consisting of a name var myObject = {x:2, y:1, z:3}
and a value.
In the reference data type, the values point to the object’s location (address) in memory.
In this diagram below, x contains address 1100, and y contains address 1300. These are
only examples to understand the reference data type.
Note: Reference data types are all technically “object,” and we refer to them collectively as
“object”. In a broader sense, all reference data types are considered as “object”. However,
depending on the context, Function, Array, Map, Set….are not “Object”. In this narrow
context, an “Object” indicates a reference data type with an unordered list of properties
consisting of a name and a value.
50
let a = {
title: "Dr.",
name: "Ada Lovelace",
amount: "100"
};
console.log(`
Dear ${a.title} ${a.name},
I am apologetic about the bad service that you have experienced at our restaurant last week.
I would like to gift you a $${a.amount} check for your continued association with us, and as a
way to make an apology.
Sincerely,
`);
Interestingly,var declarations are globally scoped or function scoped. On the other hand,
let and const are block-scoped.
var
var is a variable that can be updated and redeclared within its scope. Surprisingly there is
no block scope. You can duplicate var with the same variables name. However, in ES5
strict mode, duplication is not allowed.
let (ES6)
let variables can be updated but not redeclared. It is block-scoped and cannot be used until
declared. You cannot duplicate let with the same variables name.
If data is a reference data type, such as an array, an object, or a function, you can
still change its contents.
const (ES6)
const behaves in a very similar way to let. It is also block-scoped and cannot be used until
declared. Just Like let, you cannot duplicate let with the same variables name.
Just like let, if data is a reference data type, such as array, object, or function, you can still
change its contents.
If data is a primitive type, const variables can neither be updated nor re-declared.
On the other hand, let variables can be updated but not re-declared.
Block scope controls the visibility and lifetime of variables and parameters. Variables
declared using var do not have block scope, while variables declared using let and const
have block scope. Anything within curly braces { } is a block. A variable declared in a
block with let or const is only available for use within { }.
if (myage === 1) {
var myage = 2;
console.log(myage);
// expected output: 2
}
console.log(myage); //expected value: 2
console.log(myage1);
// expected output: 20
}
console.log(myage1); // expected output: 10
54
Any unit of code that can be evaluated to a value is referred to as an expression. Since
they produce values, expressions can appear anywhere in a program where JavaScript
expects a value, such as the arguments of a function invocation.
Logical AND operator can replace if-else statement. When x is false, right expression is
not executed. When x is true, right expression is executed.
let x = 1;
if (x === 1) {console.log("hello world 2");} //hello world 2
//using && expression – the result same as above
x === 1 && console.log("hello world 3"); //hello world 3
Logical OR operator can be used to assign the default value. When msg2 is empty, the
right value is assigned.
2.4 Iterators
Iterator is a way to loop over any collection or lists in JavaScript. It is an object with a
mechanism for enumerating the contents of an object. For example, built-in objects such
as Array, String, Map, and Set have an iterator by default so that the elements can be
enumerated by the for ... of iterator.
Symbol.iterator (ES6)
Symbol.iterator will return an iterator object. The iterator has a method next(), which
will return an object with keys value and done.
// generate iterator
const it = iterable[Symbol.iterator]()
while (true) {
// get current status
const result = it.next()
// check condition
if (result.done) {
break
}
// aquire value
const item = result.value
console.log(item). //Tokyo, Bangalore, New York
}
The comparison between classic for...in and ES6 for …of is as follows:
58
2.5 Functions
When a function is invoked, it begins execution with the first statement and ends when it
hits the curly bracket } that closes the function body. This causes the function to return
control to the part of the program that invoked the function. The return statement can be
used to cause the function to return early. When the return is executed, the function returns
immediately without executing the remaining statements.
When a function is invoked, the JavaScript interpreter creates an execution context. This
record contains information about where the function was called from (the call-stack),
how the function was invoked, what parameters were passed, etc. One of this record's
properties is this reference, which will be used for the duration of that function’s
execution.
The function declaration starts with the function keyword and includes the name of the
function following it. The contents of function are enclosed in { }.
Function declaration
function func1() {
console.log("dog1");
}
func1(); // dog1
function func2(a) {
console.log(a);
}
func2("dog2"); // dog2
Function Expression
The function expression does not require a name after the function. This is referred to as
an anonymous function. Function expressions are referenced through variables or
property. let, and const can be used as well as var.
The function expression can add a name after the function. This can be useful in
debugging.
The anonymous functions cannot invoke by themselves. The anonymous function can be
an expression if we use it where JavaScript expecting a value. That means if we can tell
JavaScript to expect a value with parentheses, we can pass an anonymous function as that
value.
The main usage is to create a closed scope that protects internal identifiers from undesired
external access. In other words, it’s a method of encapsulation.
IIFE examples
(function() {
console.log("dog5");
})(); // dog5
Arrow functions, which are often referred to as Lambda functions, are a concise way of
writing functions. Their short syntax is further enhanced by their ability to return values
implicitly in one line, single return functions. Arrow functions are always considered
anonymous functions.
is shortened to:
const myFunction = ( ) => { //...}
If the function body contains just a single statement, you can omit the brackets and write
all on a single line:
const myFunction = ( ) => doSomething()
Parameters are passed in the parentheses. If you have only one parameter, you could omit
the parentheses completely:
Arrow functions have a built-in way to shorten a return syntax. When you use curly
brackets { }, you need to return the state explicitly. However, when you don't use
curly brackets in the arrow function, the return is implied, and you can omit the
return.
is shortened to:
is shortened to:
Methods
JavaScript methods are actions that can be performed on Object. It is a property
containing a function definition. In ES6, the colon and function keywords can be
eliminated for simplicity. This coding pattern is used in the Hooks section in this book.
Arguments
Surprisingly there is no strict checking of arguments. If a function is called with missing
arguments (less than the argument declared), the missing values are set as: undefined. If a
function is called with extra arguments, it will be ignored.
function func(a, b, c) {
console.log(a, b, c)
}
//less arguments passed
func(' a') // output: a undefined undefined
// no arguments
func() // output: undefined undefined undefined
Arguments Object
The Arguments Object is an object that manages the arguments passed by the caller and is
available within the scope of the function body. Whether or not arguments are defined in
the function, the Arguments Object manages all the arguments passed to the functions.
function func1(a, b, c) {
for (let p of arguments) {
console.log(p)
}
}
func1('a', 'b', 'c', 'd') // a b c d
func1('a') // a
func1() // nothing happens
function func2() {
// structure similar to array object
console.log(arguments.length, arguments[0]);
}
func2(' x', 'y', 'z') // 3 x
Code sample: https://codesandbox.io/s/js-arguments-qh9f6
66
The function Rest parameters (…), indicated by three consecutive dot characters, allow
your functions to have a variable number of arguments without using the Arguments
Object. The Rest parameter is an instance of Array, so all array methods work.
Default parameters allow your functions to have optional arguments without checking
arguments.length or checking for undefined.
Functions as Values
JavaScript functions are first-class objects. It is one of the most important concepts in
JavaScript. You can use functions like other objects. You can assign functions to
variables, pass them to other functions as arguments, return them from functions, add
them to objects, or remove them from objects.
Functions as values
function sayHello() {
console.log("Hello World");
}
sayHello(); //output: Hello World
Anonymous functions are used for passing functions as a parameter to another function.
Anonymous functions can be executed later. It is referred to as a callback, which is like
leaving a message in the voice message to be called later. One example of a callback is
the event listener. In the event listener, the callback function registered in advance is
called when the expected event occurs. You can get used to the callback concept through
several exercises below:
callback example 1
//Passing Anonymous functions as values
// function expression that can invoke an anonymous function
const sayHi = function(myFunc) {
myFunc();
};
callback example 2
//====Passing Anonymous functions as values
const add1 = x => x + 1;
callback example 3
// functions declaration that can invoke an anonymous function
function myFunc(callback) {
console.log("hello");
callback(); //hello
}
callback example 4
//***********callback example 4 *********************
//display latitude and longitude by calling Geolocation API
//which is supported by browsers.
navigator.geolocation.getCurrentPosition(success);
function success(pos) {
console.log(`my latitude: ${pos.coords.latitude}`);
console.log(`my longitude: ${pos.coords.longitude}`);
}
Higher-Order Functions
Functions that take and/or return other functions are called Higher-Order Functions.
Below, we pass an anonymous function to the myFunc function, which we then
immediately return from the myFunc function.
Function declarations in JavaScript are hoisted to the top of the execution context -
enclosing function or global scope. You can use the function before you declared it.
However, Function expressions are not hoisting.
function myFunc() {
console.log('function hoisted')
}
Constructors
A constructor is simply a function that is used with a new keyword to create an object. The
advantage of constructors is that constructors contain the same properties and methods.
When you create many identical objects, you can create a constructor with reference types.
After the constructor is defined, you can create instances by using a new keyword.
Instances are runtime instances of Component Class. These are represented as JavaScript
objects in memory. If the functions are intended to be used as constructors, the first letter
is capitalized by convention to avoid confusion. There is no syntactic difference between
constructors and normal functions.
Many React projects have been using ES6 Class base components to handles states.
However, starting with React version 16.8.0, new projects can use Hooks, which do not
require Classes any longer. Although there are no plans to remove Classes from React,
Class base components have been replaced by Hooks in many projects. It is far cleaner
than using Classes in React. But you still need to understand the JavaScript class to
maintain and support many existing projects.
72
If a function has this reference inside, this reference usually points to an object. But which
object it points to is depending on how the function was called.
this behavior is very confusing in JavaScript. Fortunately, in React, this keyword can be
avoided by using functional components like React Hooks. However, as many existing
React projects still use Class, understanding this may still be necessary.
If you would like to practice this behavior, we would suggest the following link.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
73
An arrow function does not have its own this, but it has this value of the enclosing
execution context. Arrow Functions lexically bind their context, so this actually refers to
the originating context (defined when you write the code). The following example is ES5
function with bind(this) and Arrow function without bind(this).
Both call and apply are similar in usage. They execute a function in the context or scope of
the first argument that you pass. They are functions that can only be called on other
functions. With call, subsequent arguments are passed into the function as they are, while
apply expects the second argument to be an array that it unpacks as arguments for the
called function.
sum.call(obj1, 1, 1) // 3( 1 + 1 + 1 )
sum.call(obj2, 1, 1) // 4( 2 + 1 + 1)
sum.apply(obj1, [1, 1]) // 3( 1 + 1 + 1)
sum.apply(obj2, [1, 1]) // 4( 2 + 1 + 1)
Bind
bind( ) can be used by every single function. bind( ) returns a bound function with the
correct context this for calling the original function when executed later. bind( ) can be
used when the function needs to be called later in certain events.
obj1Sum(1, 2) // 103( 10 + 1 + 2)
obj2Sum() // 203( 200 + 1 + 2)
sumA() // 6( 1 + 2 + 3)
sumB(2, 3) // 6( 1 + 2 + 3 )
sumB(4, 5) // 10( 1 + 4 + 5 )
const obj = {
val: 'dog',
show: function() {
console.log(this) // Object {val: 'dog'}
obj.show()
Recursive function
A recursive function is a coding pattern that invokes itself until a condition is met.
In functional programming, recursion is often used instead of loop/while. The downside of
the recursion is that it consumes the stack area. It is a trade-off between simplicity and
higher memory usage.
In the code below, we start the countDown function, which then calls itself via the
function name countDown. This counts down from 5 to 0.
Memoization
In the below example, memoizedAdd returns a function that is invoked later. This is
possible because, in JavaScript, functions are first-class objects which let us use them as
higher-order functions and return another function. A cache can remember its values since
the returned function has a closure over it.
The memoized function must be pure. A pure function will return the same output for a
particular input, no matter how many times being called, which makes the cache work as
expected.
Property shorthand
ES6 syntax for creating an object literal is simple and clean.
//ES6 Shorthand
let obj2 = {
first,
last
};
console.log(obj2); // Object {first: "Ada", last: "Lovelace"}
//==============ES6 method=============================
let mathES6 = {
add(a, b) {
return a + b;
},
subtract(a, b) {
return a - b;
}
};
console.log(mathES6.subtract(10, 2)); //8
console.log(mathES6.add(4, 5)); //9
Object.assign (ES6)
The Object.assign( ) method is used to copy property values from one or more source
objects to a given target object. It will return the target object.
In the following example, Object.assign( ) method is used to create the new object by
specifying { } as the first parameter:
ES6 Object.assign(example 1)
let obj = {
firstname: "Ada",
lastname: "Lovelace"
};
let copy = Object.assign({}, obj);
console.log(copy);
The next example is to provide multiple sources as well as a target with values. The target
will receive the values from the sources and return with the values merged. The original
target variable is also changed as well, o1 being the target with o2 and o3 the two sources:
let g = 1;
let h = 2; //swapping variables
[g, h] = [h, g]
console.log(g) // 2
console.log(h) // 1
The Spread Operator expands an array into multiple parameters. It is like a reverse
operation of function rest parameters. It can also be used for object literals. It is a simple
and intuitive way to pass arguments. The Spread Operator operator makes copying and
merging arrays a lot simpler. Rather than calling the concat( ) or slice( ) method, you
could use the Spread Operator. Spread Operator is a syntax commonly used in React/
Redux.
function sum(x, y, z) {
return x + y + z
}
var myArray = [1, 2, 3]
In JavaScript, arrays are basically a data structure that holds a list of values. These values
can be strings, integers, objects, or even functions. Arrays don't have fixed types or
restricted lengths.
Includes( ) method
The includes( ) method is used to check if a specific string exists in an array,
returning true or false. It is case-sensitive.
Some( ) method
The some( ) method checks if some elements exist in an array, returning true or false. It is
similar to the concept of the includes( ) method, except the argument is a function and not a
string. (logical OR)
every( ) method
The every( ) method loops through the array, checks every item, returning true or false.
Same concept as some( ). Except every item must satisfy the conditional statement.
Otherwise, it will return false. (logical AND)
forEach( ) method
The forEach( ) method executes a provided function once for each array element.
The forEach( ) method doesn’t actually return anything (undefined). It simply calls a
provided function on each element in your array. The forEach() method allows a callback
function to mutate the current array.
map( ) method
The map( ) method creates a new array by calling a provided function on every element in
the calling array. The map( ) method is used to modify each element. The original array
is unchanged.
Array Map( )
const myArray = [50, 10, 3, 1, 2];
console.log(myArray); //[50,10,3,1,2]
Filter( ) method
The filter( ) method creates a new array with all elements that pass the test.
It lets you filter out items you do not need. The original array remains the same.
Array Filter( )
const age = [85, 25, 6, 100, 17];
reduce( ) method
The reduce( ) method is used to apply a function to each element in the array to reduce the
array to a single value. The reduce( ) transforms an array into something else, which could
be an integer, and another array, an object, a chain of promises, etc. In short, it reduces
the whole array into one value. It is used for calculating value, grouping objects by the
property, executing promises sequentially. The original array remains the same.
// 100+5+4+3+2+1
const initialValue = 100; //set initial value
const array3 = array1.reduce(myReducer, initialValue);
console.log(array3); // output: 115
const data = [
{ area: "Paris", population: 11 },
{ area: "London", population: 13 },
{ area: "Rome", population: 4 },
{ area: "Berlin", population: 6 }
];
let sum = data.reduce((acc, val) => { return val.area === "London" ? acc : acc + val.population;}, 0);
console.log(sum); // 21 (Million) metropolitan population
console.log(result2); //12
console.log(b); //1, 2, 3, 4, 5];
If you really prefer to use methods mutating original arrays, you can use Immer library.
We will learn it later.
92
A lexical scope or scope chain in JavaScript refers to the accessibility of the variables,
functions, and objects based on their physical location in the source code. The lexical
scope is defined when you write the code. No matter where the function is invoked from
or how it is invoked, its lexical scope is defined by where the function was declared.
The function scope is created for a function call execution, not for the function itself.
Every function call creates a new function scope dynamically at run time. When the
function has completed the execution, the scope is usually destroyed. The function scope
is garbage collected. (JavaScript has memory management)
function myFunc() {
const inside = 'I live in the function scope'
}
console.log(outside) //I live in the global scope
console.log(inside) //(cannot access)
93
Execution Context
An execution context is an abstract environment where the JavaScript code is evaluated
and executed. When the global code is executed, it is executed inside the global execution
context, and the function code is executed inside the function execution context.
An execution stack uses LIFO (Last-In, First-Out) buffer structure in which items can only
be added or removed from the top of the stack only. The current running execution
context will always be on the top of the stack. When the currently running function
completes the execution, its execution context is popped off from the stack, and the
control reaches the execution context below it in the stack.
Lexical Environment
In JavaScript, scopes are implemented via lexical environments. Every time the JavaScript
engine creates an execution context, it also creates a new lexical environment to store the
variable defined in that function during the execution of that function.
1. An environment record: the actual place where the variable and function
declarations are stored.
2. A reference to the outer environment: access to its outer (parent) lexical
environment. This concept is the most important to understand how closures work.
94
Closure
Most JavaScript Developers use closure consciously or unconsciously. Even if you use it
unconsciously, it may work fine in many cases. But understanding closure will provide
you better control over the code. After React Hooks had been released in 2019, React
gradually moved towards functional programming. That means understanding the closure
is one of the most important knowledge for studying React.
In JavaScript, every running function, code block, and script has an associated object
known as the Lexical Environment. A new Lexical Environment is created each time a
function is executed.
If the function has more than two-level nested inner functions, the innermost Lexical
Environment is searched first, then the more outer one, and so on until the end of the
chain.
For example, we write a two-level nested function like a Closure example 2b. When this
function is called multiple times, each invocation will have its own Lexical Environment,
with local variables and parameters specific for that very run. When the code wants to
access a variable – the inner Lexical Environment is searched first, then the outer one.
In plain English, a closure is a function with access to its outer function scope even
after the outer function has returned. This means a closure can remember and access
variables and arguments of its outer function even after the function has been
completed.
Typically, a function has local variables in its code body, including any parameters, and it
also might have valuables that are not defined locally nor global valuables. These
valuables are called free valuables. Closures are functions that refer to free variables. In
other words, the function defined in the closure remembers the environment in which
it was created.
95
One of the key principles in creating closures is that an “inner” function, which is declared
inside another function, has full access to all of the variables declared inside the scope of
the function in which it’s declared (the “outer” function). In other words, the inner
function preserves the scope chain of the enclosing function at the time the enclosing
function was executed. Therefore, it can access the enclosing function’s variables.
The following example shows the scope of the inner function and the outer function. The
outer( ) function has access to the variable outside only, which is declared in its scope. On
the other hand, the inner( ) function has access to the variable inside and the variable
outside.
function outer() {
const outside = 'I live outside!';
function inner() {
const inside = 'I live inside!';
console.log(outside); //I live outside!
console.log(inside); //I live inside!
}
return inner;
}
const myclosure = outer();
myclosure();
The following example is a counter without closure. The problem is that each time
xcounter is called, the global variable xcount is incremented. Global variables could clash
with the names of other variables.
function xcounter() {
return ++xcount;
}
console.log(xcounter()); //1
console.log(xcounter()); //2
console.log(xcounter()); //3
97
The following example is a counter with local and protected variable i. The inner function
creates an independent execution context containing variable i. The returned function can
refer to the variable i, even after the outer function is terminated. Therefore each time
count is invoked, the variable i is incremented from the previous value. The closure keeps
the execution context.
function counter(init) {
let i = init
return function() {
return ++i
}
}
const count = counter(100)
console.log(count()) //101
console.log(count()) //102
console.log(count()) //103
In the following example, count10 and count100 maintain their independence from the
other. Each closure references a different version of the private counter variable through
its own closure. Each time one of the counters is called, its lexical environment is updated
by changing the value of this variable. However, changes to the variable value in one
closure do not affect the value in the other closure. We have access to variables defined in
the enclosing function(s) even after the enclosing function, which defines these variables,
has returned.
function counter(init) {
let i = init
return function() {
return i++
}
}
const count10 = counter(10)
const count100 = counter(100)
console.log(count10()) //10
console.log(count100()) //100
console.log(count10()) //11
console.log(count100()) //101
In the following example, we define a function adder(x), which takes a single argument x,
and returns another function. The returning function takes a single argument y and
returns the sum of x and y. adder(x) creates functions that can add a specific value to
their argument.
We use adder(x) to create two new functions — add10 for adding 10 and add100 for
adding 100. add10 and add100 share the same function body definition but store different
lexical scope environments. In the lexical scope environment for add10, x is 10, while in
the lexical scope environment for add100, x is 100.
Using a closure, a function can remember and access its lexical scope even when that
function is executing outside its lexical scope.
function adder(x) {
return function(y) {
return x + y
}
}
console.log(add10(5)) // 15
console.log(add100(5)) // 105
JavaScript Methods can be used as well to create closures. This example produces an
object containing two closures: inc and reset properties. Each closure shares access to the
n variable. The inc closure updates the value of n, and reset closure clears the values of n.
function xcounter() {
var n = 0;
return {
inc: function() {
return ++n;
},
reset: function() {
n = 0;
}
};
}
Curry
Named after Haskell Curry, Curry is the process of breaking down a function into a
series of functions that take a single argument. A curried function is a function that
takes multiple arguments one at a time. A curried function will be split into many chained
functions, all taking exactly one argument. A curried function works by creating a closure
that holds the original function and the arguments. With Curry, functions become more
predictable and reusable. For example, Redux middleware uses Curry. The below
examples un-curried and curried functions.
Partial Application
Partial application is a technique used to transform functions with multiple arguments into
multiple functions that take fewer arguments. A function can be called with fewer
arguments than it expects. And the function returns a function that takes the remaining
arguments. And this is called the Partial Application of functions. A curried function will
be split into many chained functions, all taking exactly one argument, but a partially
applied function does not have that limitation.
Partial Application
//call a function with fewer arguments than it expects.
//And the function returns a function that takes the remaining arguments.
console.log(add1(10)); //11
console.log(add2(10)); //12
city1.sayName();
city2.sayName();
ES6 Classes
JavaScript does not have Classes. JavaScript uses Prototypes, singleton objects from
which other objects inherit. In fact, all objects in JavaScript have a prototype from which
they inherit. This means that JavaScript Classes do not behave exactly like conventional
Classes. You can actually add a new method to an array, and suddenly all arrays can use it.
This can be done in runtime, affecting an already instanced object.
ES6 Class is merely syntax sugar of the prototypes with constructers. JavaScript
developers who want to implement classical inheritance can use ES6 Classes and avoid
explicit use of prototypes:
ES6 class
class Point1 {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return this.x + ", " + this.y;
}
}
Subclassing
The extends clause lets you create a subclass of an existing constructor (which may or may
not have been defined via a class):
ES6 subclass
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return this.x + ", " + this.y;
}
}
Computers are synchronous systems from digital circuits point of view. Generally, all
internal logic gates are synchronized with the system clock. However, computers are
asynchronous from a high-level systems point of view. Normally, programming
languages are synchronous, and some provide a way to manage the asynchronous
operation, using the language or through libraries. C, Java, C#, PHP, Go, Ruby, Swift,
Python are all synchronous by default. Some of them handle async by using threads,
spawning a new process. Unlike most languages, JavaScript is asynchronous by default
and is single-threaded. This means that code cannot create new threads and run in parallel.
However, commands which can take any amount of time do not halt the execution. That
includes operations such as requesting a URL, reading a file, or updating a database. The
asynchronous event handling of JavaScript is similar to the event driven RTOS (Real
Time Operation System) in low-level software.
The below picture is a comparison between the synchronous process and the asynchronous
process. The synchronous process executes task 1a à1b à 1c à 2a à2b à2c
sequentially. If one of the tasks blocks the execution, it would add the total system delay.
On the other hand, the asynchronous process does not block the process. Even if one of
the tasks blocks the execution, it would not add to the total system delay.
time
1b and 2b below are external event delay, such as timer delay, external resources access.
Task 1 Task 2
Synchronous Process 1a 1
1b 1c 2a 2b 2c
Task 1
Asynchronous Process 1a 1b 1c
2a 2b 2c
1b Task 22b
107
The following example and diagram could help you understand the asynchronous process
with a timer event. The setTimeout() method calls a function that evaluates an expression
after a specified number of milliseconds. As the setTimeout() method does not block the
next processing, “test point 3” is displayed before displaying “test point 2”.
setTimeout(function() {
//setTimeout triggers an asynchronous operation.
console.log("test point 2");
}, 2000);
console.log("test point 3"); //this runs while waiting for the 2 sec. timeout.
//expect result
// test point 1
// test point 3
// test point 2
function doSomething() {
doSomething1((response1) => {
doSomething2(response1, (response2) => {
doSomething3(response2, (response3) => {
// etc...
};
});
});
}
109
Promise
ES6 introduced Promises, which provided a cleaner way to express the same functionality.
A promise represents a value that we can handle at some point in the future. A promise is
an object which can be returned synchronously from an asynchronous function. Promises
give us advantages over callbacks:
• No other registered handlers of that value can change it. A promise contract is
immutable.
• We are guaranteed to receive the value, regardless of when we register a handler
for it, even if it’s already resolved. This contrasts with conventional events - once
an event is fired, you can’t access its value at a later time.
• The promise can handle multiple asynchronous operations easily and provide
better error handling than callbacks and events.
Creating Promise
new promise(function (resolve, reject) {…..}) return promise
myPromise2.then(res => {
console.log(res); //my promise 2
});
In the below example we are calling reject after 2 sec delay. then( ) can also take in a
second handler for errors.
Promise.all
function delay(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms);
});
}
Promise.all([
delay(2000).then(() => "second."),
delay(1000).then(() => "first.")
])
.then(function(txt) {
console.log(txt); //["second", "first"]
})
.catch(function(err) {
console.log("error:", err);
});
Like Promise.all, it takes an iterable of promises, but instead of waiting for all of them to
finish, it waits for the first result (or error) and returns a promise.
Promise.race
function delay1(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms);
});
}
Promise.race([
delay1(4000).then(() => "second."),
delay1(3000).then(() => "first.")
])
.then(function(txt) {
console.log(txt); //first
})
.catch(function(err) {
console.log("error:", err);
});
Promise new Promise(function The promise global creates promise objects that have the
(resolve, reject) {…} two methods - then and catch.
return promise
promise.then promise.then The promise.then() method accepts an onFulfilled and
([onFulfilled], onRejected callback. The function returns a promise that
[onRejected]) is resolved by the return value of the onFulfilled or
returns promise onRejected callback. Any errors thrown inside the
callback rejects the new promise with that error.
promise.catch promise.catch The catch() method returns a Promise and deals with
(onRejected) rejected cases only if the callback throws an error. You
returns promise must explicitly re-throw an error inside a catch callback.
Generators (ES6)
Generators are functions that can be paused and resumed instead of executing all the
statements of the function in one shot. They simplify iterator-authoring using the function*
and yield keywords. A function declared as function* returns a Generator object.
The Generator function can be implemented in ES3/ES5 through the closures, returning an
iterator object that will remember its own state. However, it is more complicated to
implement to be adapted to each use case. We recommend using ES6 generator syntax.
116
In the following example, we will create a generator named genFunc. We are pausing in
the middle of the function using the yield keyword. When we call the function, it won’t be
executed until we iterate over the function, and so here, we iterate over it using the next
function. The next function will run until it reaches a yield statement. Here it will pause
until another next function is called. This, in turn, will resume and continue executing until
the end of the function.
generator
function* example
genFunc() { 1
console.log("First"); // First
yield;
console.log("Second"); //Second
yield;
console.log("Third"); //Third
}
let gen1 = genFunc();
console.log(gen1.next()); //{ value=undefined done=false}
console.log(gen1.next()); //{ value=undefined done=false}
console.log(gen1.next()); //{ value=undefined done=true }
generator example 2
function* foodGenerator() {
console.log("First"); //output: First
yield "Sushi"; //return “Sushi” to caller
async/await (ES8)
async/await functions expand on Promises+Generators to make asynchronous calls even
cleaner. The async function declaration defines an asynchronous function, which returns
an asynchronous function object. An asynchronous function operates asynchronously via
the event loop, using an implicit Promise to return its result. But the syntax and structure
of your code using async functions are still like using conventional synchronous functions:
await effectively makes each call appear as if it’s a synchronous operation while not
holding up JavaScript’s single processing thread.
118
async
We will start with the async keyword. It is placed before function, like below:
async function f(){ return "promise 1 done";} f().then(alert);
// "promise 1 done!"
The keyword async before a function means that a function always returns a Promise. If
the code has return <non-promise> in it, then JavaScript automatically wraps it into a
resolved promise with that value. For instance, the code above returns a resolved Promise
with the result "promise 1 done".
async ensures that the function returns a Promise, wraps non-promises in it. And there is
another keyword await that works only inside async functions.
119
await
The keyword await makes JavaScript wait until that Promise settles and returns its result.
Below is an example with a Promise that resolves in 2 seconds:
myFunc()
console.log("Please wait") //while waiting, this is executed
The function execution “pauses” at the line (*) and resumes when the Promise settles. So
the code above shows “promise 3 done!” in 2 seconds. await literally makes JavaScript
wait until the Promise settles and then go on with the result. However, that doesn’t cost
any CPU resources because the JavaScript engine can execute other tasks while waiting.
120
Fetch API
The Fetch API provides an interface for accessing and manipulating parts of the HTTP
sequence, such as requests and responses. It also provides a global fetch( ) method that
provides a simple, logical way to fetch resources asynchronously across the network.
The fetch( ) method takes one mandatory argument that indicates the path to the resource
you want to fetch, and it returns a Promise that resolves with an object of the built-in
Response class as soon as the server responds with headers.
The code below shows a basic fetch request in which we are fetching a JSON file across
the network.
When receiving data without errors and assuming that we expect a JSON response, we
first need to call the json( ) method to transform the Response object into an object that we
can interact with.
There are a number of methods available to define the body content in various formats:
response.json(), response.text(), response.formData(), response.blob(),
response.arrayBuffer()
Axios library
Axios is a JavaScript library that helps us make HTTP requests to external resources and
supports the Promise API.
Unlike Fetch API, Axios does not come as a native JavaScript API, but there are many
advantages over fetch API.
On the other hand, Fetch API supports lower-level operations and more flexible than
Axios.
The code below shows a basic fetch request in which we are fetching JSON data across
the network. With Fetch API, we need to deal with two promises. With Axios, we can
directly access the JSON result inside of the response object data property.
Axios also provides functions to make other network requests as well, matching the HTTP
verbs that you wish to execute:
2.10 Modules
ES6 supports modules using import/export syntax. You can use the export keyword to
export parts of code to other modules. And when you have a module with exports, you can
access the functionality in another module by using the import keyword.
Named exports
Named exports are useful to export several values. During the import, you can use the
same name to refer to the corresponding value. Exported functions can be used by other
modules by using import syntax. It is also possible to export all the variables in one area
by using this syntax for listing. You can import all of the module’s functionality by using
import * as <Namespace> syntax.
// export a constant
export const year = 2050;
// export function
export const hello1 = function() {console.log("Hello World 1");};
console.log(months); //{"Jan","Feb","Mar".....}
console.log(year); //2050
Default export
The other type of export is a default export. A module can contain only one default export.
A default export can be a function, a class, an object, or anything else. This value is
considered as the “main” exported value since it will be the simplest to import.
This is a common pattern for libraries because you can import the library without
specifying each library.
It is common for a module using mixing of both named exports and default exports.
ReactDOM .render(
// …
);
In case of using only render( ) function , the named render( ) function can be imported like
this.
import {render} from ‘react-dom’;
render(
// …
);
const ReactDom = {
render,
// … other functions
};
ISBN-13 : 979-8525800144
127
This book helps you learn ReactJS, React Hooks, Redux, Redux Middleware, Redux-
Thunk, Redux-Saga, RTK, Recoil, XState, SWR, React Router, Jest, React Test Library,
and various React related technology.
With 99 CodeSandbox code examples we have created, you can run sample programs in
your browser, no need to waste your time by setting up the environment. The goal is to
help you learn the React ecosystem quickly and guide you in the right direction.
• JavaScript beginners: some experience in Web design using HTML, CSS, and
JavaScript.
• JavaScript programmers who are not familiar with functional programming and
ES6.
• Busy developers who do not have time to go through React/Redux official
documentations.
• Non-Web software engineers, managers, or system architects: at least know one of
the high-level languages.
Learning schedule:
• Overview (one hour reading)
• Redux, Middleware, Thunks, Saga, and RTK (12 hours reading and exercise)
CodeSandbox environment:
You will need a Windows PC, Mac, Chromebook, Android device, iOS device, or Linux-
based device. We have tested all code on Chrome, Firefox, and Edge browser.
129
About an author
Satoshi Yoshida started his professional carrier in the 1980s, developing CPU circuits,
mobile phone modem LSIs and firmware. He also had management and architect
experiences in various multinational companies in Japan, Canada, France, and Germany.
He has 16 patents in wireless communication and has been working as a freelance
consultant (wireless hardware, IoT, smart metering, UI software) since 2018.
About a co-author
Simona Yoshida has been working on web-based UI software and e-commerce platform
since 2015. Sample codes in chapter 2, chapter 3, and chapter 4 were written and tested
by her. In her spare time, she takes care of dogs and cats from animal shelters.
Recommendation by BookAuthority.org:
- 14 Best New React Hooks Books To Read In 2021
As featured on CNN, Forbes and Inc – BookAuthority identifies and rates the best books
in the world, based on recommendations by thought leaders and experts.
https://bookauthority.org/books/new-react-hooks-books
Amazon.com (USA)
Amazon.co.uk (UK)
Amazon.de (Germany)
Amazon.fr (France)
Amazon.es (Spain)
Amazon.it (Italy)
Amazon.nl (Netherlands)
Amazon.co.jp (Japan)
Amazon.in (India)
Amazon.ca (Canada)
Amazon.com.br (Brasil)
Amazon.com.mx (Mexico)
Amazon.com.au (Australia)