Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
2 views

ReactRouter-Redux-API

React Router is the standard routing library for React, enabling navigation through applications with multiple views while keeping the UI and URL in sync. It supports single-page applications (SPAs) by allowing unique URLs for each view, maintaining browser navigation functionality, and enabling nested routing. The document outlines the setup, basic components, and routing concepts, including the use of <Route>, <Link>, and <Switch> components for effective routing management.

Uploaded by

Wissem Chehaider
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

ReactRouter-Redux-API

React Router is the standard routing library for React, enabling navigation through applications with multiple views while keeping the UI and URL in sync. It supports single-page applications (SPAs) by allowing unique URLs for each view, maintaining browser navigation functionality, and enabling nested routing. The document outlines the setup, basic components, and routing concepts, including the use of <Route>, <Link>, and <Switch> components for effective routing management.

Uploaded by

Wissem Chehaider
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 89

React Router

React Router : Overview


Introduction
React Router is React's standard routing library. When you need to
navigate through a React application with multiple views, you’ll need a
router to manage the URLs. React Router does that while keeping your
application's UI and URL in sync.

One of the main features of React is that it allows the creation of single-
page applications (SPAs) that are rendered on the client's side. An SPA
might have multiple views (aka pages), and unlike the conventional
multi-page apps, navigating through these views should not result in the
entire page being reloaded. Instead, we want the views to be rendered
inline within the current page. The end user, who’s accustomed to multi-
page apps, expects the following features to be present in an SPA:

 Each view in an application should have a URL that uniquely


specifies that view. This is so that the user can bookmark the URL for
reference at a later time — e.g. www.example.com/products.
 The browser’s back and forward button should work as expected.
 The dynamically generated nested views should preferably have a
URL of their own too — e.g. www.example.com/products/shoes/101,
where 101 is the product id.

Routing is the process of keeping the browser URL in sync with what’s
being rendered on the page. React Router lets you handle
routing declaratively. The declarative routing approach allows you to
control the data flow in your application, by saying “the route should look
like this”:
<Route path="/about" component={About}/>

You can place your <Route> component anywhere that you want your
route to be rendered. Since <Route>, <Link> and all the other React
Router API that we’ll be dealing with are just components, you can easily
get used to routing in React.

One remark before getting started. There’s a common misconception that


React Router is an official routing solution developed by Facebook. In
reality, it’s a third-party library that’s widely popular for its design and
simplicity. If your requirements are limited to routers for navigation, you
could implement a custom router from scratch without any hassle.
However, understanding the basics of React Router will give you better
insights into how a router should work.
Overview

In this Super Skill, we'll cover four main topics. First, we’ll be setting up
React and React Router using npm. Then we’ll jump right into React
Router basics. You’ll find different code demonstrations of React Router in
action. The examples covered include:

 Basic navigational routing.


 Nested routing.
 Nested routing with path parameters.
 Protected routing.

Let’s get started!

Setting up React Router


Let's assume you already have a development environment up and
running where you've used Create React App to generate the files required
for creating a basic React project. The default directory structure
generated by Create React App should look something like this:
react-routing-v4-superskill

├── README.md

├── node_modules

├── package.json

├── .gitignore
├── public

│ ├── favicon.ico

│ ├── index.html

│ ├── logo192.png

│ ├── logo512.png

│ ├── manifest.json

│ └── robots.txt

└── src

├── App.css

├── App.js

├── App.test.js

├── index.css

├── index.js

├── logo.svg

└── serviceWorker.js

The React Router library comprises three packages: react-router, react-


router-dom, and react-router-native. react-router is the core package for the
router, whereas the other two are environment-specific. You should
use react-router-dom if you’re building a website, and react-router-native if
you’re on a mobile app development environment using React Native.

Let's use npm to install react-router-dom:


npm install --save react-router-dom

Fill in the blanks Solution


react-router: provides the core routing components and functions for the React
Router applications. react-router-native: is used for mobile applications. react-router-
dom: is used for web applications design.

React Router Basics


React Router Basics
Here’s an example of how our routes will look like:
<Router>

<Route exact path="/" component={Home} />

<Route path="/category" component={Category} />

<Route path="/login" component={Login} />

<Route path="/products" component={Products} />

</Router>

Router
You need a router component and several route components to set up a
basic route as exemplified in the previous screen. Since we’re building a
browser-based application, we can use two types of routers from the React
Router API:

1. <BrowserRouter>
2. <HashRouter>

The primary difference between them is evident in the URLs that they
create:
// <BrowserRouter>

http://example.com/about

// <HashRouter>

http://example.com/#/about

Router
The <BrowserRouter> is more popular amongst the two because it uses the
HTML5 History API to keep track of your router history. The <HashRouter>,
on the other hand, uses the hash portion of the URL ( window.location.hash)
to remember things. If you intend to support legacy browsers, you should
stick with <HashRouter>.

Wrap the <BrowserRouter> component around the App component.

In index.js:
/* Import statements */

import React from 'react';

import ReactDOM from 'react-dom';


/* App is the entry point to the React code.*/

import App from './App';

/* import BrowserRouter from 'react-router-dom' */

import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(

<BrowserRouter>

<App />

</BrowserRouter>

, document.getElementById('root'));

Note: A router component can only have one single child element. The
child element can be an HTML element — such as div — or a react
component.

For the React Router to work, you need to import the relevant API from
the react-router-dom library. Here We’ve imported
the BrowserRouter into index.js. We’ve also imported the App component
from App.js. App.js, as you might have guessed, is the entry point to React
components.
The above code creates a history instance for our entire App component.

Let us now formally introduce you to history.

Fill in the blanks Solution


<BrowserRouter> keeps track of a router's history using the HTML5 History
API. <HashRouter> keeps track of a router's history using the hash portion of the
URL. The <BrowserRouter/> and the <HashRouter/> are two component exported
from react-router-dom.

history Links and Routes


history
history is a JavaScript library that lets you easily manage session history
in any JavaScript environment. History provides a minimal API that lets
you manage the history stack, navigate, confirm navigation, and persist
state between sessions. — React Training docs
Each router component creates a history object that keeps track of both
the current locations (history.location) and the previous locations in a
stack. When the current location changes, the view is re-rendered and you
get a sense of navigation and interaction. How does the current location
change? The history object has methods such
as history.push() and history.replace() to take care of
that. history.push() is invoked when you click on a <Link> component,
and history.replace() is called when you use <Redirect>. Other methods —
such as history.goBack() and history.goForward() — are used to navigate
through the history stack by going back or forward a page.

Links and Routes


• The <Route> component is the most important component in React
router. It renders a part of the UI if the current location matches the
route’s path. Ideally, a <Route> component should have a prop
named path and if the pathname is matched with the current location, it
gets rendered.

• The <Link> component, on the other hand, is used to navigate between


pages. It’s comparable to the HTML anchor element. However, using
anchor links would result in a browser refresh, which we don’t want to
happen. So instead, we can use <Link> to navigate to a particular URL and
have the view re-rendered without a browser refresh.

Fill in the blanks Solution


Link is used to navigate through the internal routes in our router application. It is the
equivalent of anchor tags: <a> </a>. It passes the string argument ‘to’ to wherever
the URL’s path is specified. The <Route> will return null in case the
specified URL doesn’t match the defined path. The basic <Route> takes two
arguments, one for the path and one for rendering UI.

Demo 1: Basic Routing


We’ve covered everything you need to know in order to create a basic router.
Let’s try and build one:
src/App.js

/* Import statements */

import React, { Component } from 'react';

import { Link, Route } from 'react-router-dom';

/* Home component */

const Home = () => (


<div>

<h2>Home</h2>

</div>

/* Category component */

const Category = () => (

<div>

<h2>Category</h2>

</div>

/* Products component */

const Products = () => (

<div>

<h2>Products</h2>

</div>

/* App component */

const App = () =>{

return (

<div>

<nav className="navbar navbar-light">

<ul className="nav navbar-nav">

/* Link components are used for linking to other views */

<li><Link to="/">Homes</Link></li>

<li><Link to="/category">Category</Link></li>
<li><Link to="/products">Products</Link></li>

</ul>

</nav>

/* Route components are rendered if the path prop matches the


current URL */

<Route path="/" component={Home}/>

<Route path="/category" component={Category}/>

<Route path="/products" component={Products}/>

</div>

Demo 1: Basic Routing


We’ve declared the components for Home, Category and Products
inside App.js. This is fine enough for now, but when the components start
to grow bigger, it’s better to have a separate file for each component. As a
rule of thumb, we usually create a new file for a component if it occupies
more than 10 lines of code. (Starting from the second demo, we’ll be
creating a separate file for components that have grown too big to fit
inside the App.js file).

Inside the App component, we’ve written the logic for routing.
The <Route>‘s path is matched with the current location and a component
gets rendered. The component that should be rendered is passed in as a
second prop.

Here / matches both / and /category. Therefore, both the routes are
matched and rendered. How do we avoid that? We should pass the exact=
{true} props to the router with path='/':

<Route exact={true} path="/" component={Home}/>

If you want a route to be only rendered when the paths are exactly the
same, you should use the exact props.
Assessment: Quiz
We use exact={true} to impose further restrictions on path matching.

True False
The Route component exists in React modules.

True False
In which path will the login component appear?

<Route path="/login" component={Login} />

/login /login/person /

Switch component and its props


Nested Routing
To create nested routes, we need to have a better understanding of
how <Route> works. Let's further explain it.

<Route> has three props that you can use to define what gets rendered:

 component. We’ve already seen this in action. When the URL is


matched, the router creates a React element from the given
component using React.createElement.
 render. This is handy for inline rendering. The render prop expects
a function that returns an element when the location matches the
route’s path.
 children. The children prop is similar to render in that it expects a
function that returns a React element. However, the children prop
gets rendered regardless of whether the path is matched with the
location or not.

Path and match


The path is used to identify the portion of the URL that the router should
match. It uses the Path-to-RegExp library to turn a path string into a
regular expression. It will then be matched against the current location.

If the router’s path and the location are successfully matched, an object is
created and we call it the match object. The match object carries more
information about the URL and the path. This information is accessible
through its properties as listed below:
 match.url. A string that returns the matched portion of the URL. This is
particularly useful for building nested <Link>s
 match.path. A string that returns the route’s path string — that
is, <Route path="">. We’ll be using this to build nested <Route>s.
 match.isExact. A boolean that returns true if the match is exact (without
any trailing characters).
 match.params. An object containing key/value pairs from the URL parsed
by the Path-to-RegExp package.

Switch Component
Before we proceed to the demo code, let's get acquainted with
the <Switch> component.
When multiple <Route>s are used together, all the routes that match are
rendered inclusively. Consider this code from demo 1. We’ve added a new
route to demonstrate why <Switch> is useful.
<Route exact path="/" component={Home}/>

<Route path="/products" component={Products}/>

<Route path="/category" component={Category}/>

<Route path="/:id" render = {()=> (<p> I want this text to show up for
all routes other than '/', '/products' and '/category' </p>)}/>

If the URL is /products, all the routes that match the location /products are
rendered. So, the <Route> with path :id gets rendered along with
the Products component. This is by design. However, if this is not the
behavior you’re expecting, you should add the <Switch> component to your
routes. With <Switch>, only the first child <Route> that matches the location
gets rendered.

Solution : Reorder statements


Knowing that Switch checks each route for a match sequentially and stops once the
first match is found. How would you tactically order the path ‘users/:id’ and ‘users’ to
have a correct match for each time:
<switch>

<route path="/users/:id" component={User}/>

<route path="/users" component={Roster}/>

</switch>

Demo 2: nested routing


Demo 2: nested routing
Previously, we've created routes for /, /category and /products. What if we
wanted the URL of the /category/shoes form?

src/App.js
import React from 'react';

import { Link, Route, Switch } from "react-router-dom";

import Category from "./Category";

const App = () => {

return (

<div>

<nav className="navbar navbar-light">

<ul className="nav navbar-nav">

<li>

<Link to="/">Homes</Link>

</li>

<li>

<Link to="/category">Category</Link>

</li>

<li>

<Link to="/products">Products</Link>

</li>

</ul>

</nav>

<Switch>

<Route exact path="/" component={Home} />

<Route path="/category" component={Category} />

<Route path="/products" component={Products} />

</Switch>

</div>
);

};

export default App;

/* Code for Home and Products component omitted for brevity */

Unlike the earlier version of React Router, which is version 4, the


nested <Route>s should preferably go inside the parent component. To be
more preicse, the Category component is the parent here, and we’ll be
declaring the routes for category/:name inside the parent component.

src/Category.jsx
import React from 'react';

import { Link, Route } from 'react-router-dom';

const Category = ({ match }) => {

return( <div> <ul>

<li><Link to={`${match.url}/shoes`}>Shoes</Link></li>

<li><Link to={`${match.url}/boots`}>Boots</Link></li>

<li><Link to={`${match.url}/footwear`}>Footwear</Link></li>

</ul>

<Route path={`${match.path}/:name`} render= {({match}) =>( <div> <h3>


{match.params.name} </h3></div>)}/>

</div>)

export default Category;

So let's explain what we did in that previous screen. First, we’ve


declared a couple of links for the nested routes. As previously
mentioned, match.url will be used for building nested links
and match.path for nested routes. If you’re having trouble
understanding the match concept, console.log(match) provides some
useful information that might help clarify things.
<Route path={`${match.path}/:name`}

render= {({match}) =>( <div> <h3> {match.params.name} </h3></div>)}/>

This is our first attempt at dynamic routing. Instead of hard-


coding the routes, we’ve used a variable within the
pathname. :name is a path parameter and it catches everything
after category/ until another forward slash is encountered. So, a
pathname like products/running-shoes will create a params object as follows:
{

name: 'running-shoes'

The captured data should be accessible


at match.params or props.match.params depending on how the props are
passed. The other interesting thing is that we’ve used
a render prop. render props are pretty handy for inline functions that
don’t require a component of their own.

Fill in the blanks Solution


< Route path ={`${match.path }/:name`} render= {({match}) =>( <div> <h3>
{ match.params.name} </h3></div>)}/>

Demo 3: Nested Routing with Path


parameters
Demo 3: Nested Routing with Path
parameters
Let’s complicate things a bit more, shall we? A real world router has to
process data and display it efficiently. Let's suppose that we have product
data returned by a server API as shown in the form below.

src/Products.jsx
const productData = [
{

id: 1,

name: 'NIKE Liteforce Blue Sneakers',

description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.


Proin molestie.',

status: 'Available'

},

id: 2,

name: 'Stylised Flip Flops and Slippers',

description: 'Mauris finibus, massa eu tempor volutpat, magna dolor


euismod dolor.',

status: 'Out of Stock'

},

id: 3,

name: 'ADIDAS Adispree Running Shoes',

description: 'Maecenas condimentum porttitor auctor. Maecenas viverra


fringilla felis, eu pretium.',

status: 'Available'

},

id: 4,

name: 'ADIDAS Mid Sneakers',

description: 'Ut hendrerit venenatis lacus, vel lacinia ipsum


fermentum vel. Cras.',

status: 'Out of Stock'

},
];

We need to create routes for the following paths:

 /products. This should display a list of products.


 /products/:productId. If a product with the :productId exists, it should
display the product data, and if not, it should display an error
message.

src/Products.jsx
/* Import statements have been left out for code brevity */

const Products = ({ match }) => {

const productsData = [

id: 1,

name: 'NIKE Liteforce Blue Sneakers',

description: 'Lorem ipsum dolor sit amet, consectetur adipiscing


elit. Proin molestie.',

status: 'Available'

},

//The rest of the data has been left out for code brevity.

];

/* Create an array of `<li>` items for each product

var linkList = productsData.map( (product) => {

return(

<li>

<Link to={`${match.url}/${product.id}`}>

{product.name}
</Link>

</li>

})

return(

<div>

<div>

<div>

<h3> Products</h3>

<ul> {linkList} </ul>

</div>

</div>

<Route path={`${match.url}/:productId`}

render={ (props) => <Product data= {productsData}


{...props} />}/>

<Route exact path={match.url}

render={() => (

<div>Please select a product.</div>

)}

/>

</div>

First, we created a list of <Links>s using the productsData.ids and stored it


in linkList. The route takes a parameter in the path string which
corresponds to the parameter of the product id.
<Route path={`${match.url}/:productId`}

render={ (props) => <Product data= {productsData} {...props} />}/>

You may have expected component = { Product } instead of the inline


render function. The problem is that we need to pass down productsData to
the product component along with all of the existing props. Although there
are other ways you can do this, we find this method to be the
easiest. {...props} uses the ES6’s spread syntax to pass the whole props
object to the component.

Here’s the code for Product component:


src/Product.jsx
/* Import statements have been left out for code brevity */

const Product = ({match,data}) => {

var product= data.find(p => p.id == match.params.productId);

var productData;

if(product)

productData = <div>

<h3> {product.name} </h3>

<p>{product.description}</p>

<hr/>

<h4>{product.status}</h4> </div>;

else

productData = <h2> Sorry. Product doesnt exist </h2>;

return (

<div>

<div>

{productData}

</div>

</div>

)
}

The find method is used to search the array for an object with an id
property that equals match.params.productId. If the product exists,
the productData is displayed. If not, a “Product doesn’t exist” message is
rendered.

Fill in the blanks Solution


< Route exact path ={`${match.url}/: productId`} render={ (props) => <Product
data= {productsData} {...props} />}/>

React Routes
Protecting Routes
For the final demo, we’ll be discussing a few techniques on how to protect
routes. So, if someone tries to access /admin, they’d be required to log in
first. However, there are some things we need to cover before we can
protect routes.

Redirect
Like the server-side redirects, <Redirect> will replace the current location in
the history stack with a new location. The new location is specified by the
'to' prop. Here’s how we’ll be using <Redirect>:
<Redirect to={{pathname: '/login', state: {from: props.location}}} />

So, if someone tries to access the /admin while logged out, they’ll be
redirected to the /login route. The information about the current location
is passed via state, so in case the authentication is successful, the user
can be redirected back to the original location. Inside the child component,
you can access this information at this.props.location.state.

Custom Routes
A custom route is a fancy term for a route nested inside a component. If
we need to make a decision whether a route should be rendered or not,
writing a custom route is the way to go.
Here’s the custom route declared among other routes.

src/App.js
/* Add the PrivateRoute component to the existing Routes */

<Switch>
<Route exact path="/" component={Home} data={data}/>

<Route path="/category" component={Category}/>

<Route path="/login" component={Login}/>

<PrivateRoute authed={fakeAuth.isAuthenticated} path='/products'


component = {Products} />

</Switch>

fakeAuth.isAuthenticated returns true if the user is logged in and false if he


is logged out.

Custom Routes
Here’s the definition for PrivateRoute:
src/App.js
/* PrivateRoute component definition */

const PrivateRoute = ({component: Component, authed, ...rest}) => {

return (

<Route

{...rest}

render={(props) => authed === true

? <Component {...props} />

: <Redirect to={{pathname: '/login', state: {from:


props.location}}} />} />

The route renders the Admin component if the user is logged in. Otherwise, the
user is redirected to /login. The good thing about this approach is that it is
evidently more declarative. PrivateRoute remains highly reusable.

Custom Routes
Finally, you can see the code for the Login component as shown below:
src/Login.jsx
const Login = props => {
const [redirectToReferrer, setRedirectToReferrer] = useState(false);

const login = () => {

fakeAuth.authenticate(() => setRedirectToReferrer(true));

};

const { from } = props.location.state || { from: { pathname: "/" } };

if (redirectToReferrer) {

return <Redirect to={from} />;

return (

<div>

<p>You must log in to view the page at {from.pathname}</p>

<button onClick={login}>Log in</button>

</div>

);

};

export const fakeAuth = {

isAuthenticated: false,

authenticate(cb) {

this.isAuthenticated = true;

setTimeout(cb, 100);

};

The line below demonstrates object destructuring, which is a part of the ES6
specification.
const { from } = this.props.location.state || { from: { pathname:
'/' } }

Protecting Routes
Let us connect the dots together. Here’s the final demo of the application
that we've built using React router:
Demo

Assessment: Quiz
The custom routes are predefined in React.

True False
The redirect component replaces the current location in the history stack.

True False
Private routes are used to make components visible only to specific users.

True False

Conclusion
Recap
React Router is a powerful library that complements React by building
better and more declarative routes. Unlike the previous versions of React
Router, in version 4, everything is “just components”. Moreover, the new
design pattern perfectly fits into the React way of doing things.

We've covered:

 how to setup and install React Router.


 the basics of routing and some essential components such
as <Router>, <Route> and <Link>.
 how to create a minimal router for navigation and nested routes.
 how to build dynamic routes with path parameters.

Redux
Redux Overview
Introduction
One of the features provided by React is one-way data flow. Although this
feature can help developers debug and track data, when we get to state
management (especially when the application grows over time), it can
open the door to hell.

Redux is one of the most known and used state management libraries.
Managing states with Redux will be our main interest in this Super Skill.
Here is what we’re going to see:

 What is Redux?
 The mechanism that Redux uses to manage states.
 Redux middleware.
 Redux with hooks.

Managing states with React


By definition, a state is an object that defines the current condition of our
application.
Since React is a component-based UI library, which uses the state to track
the moving parts of the user interface, state management in applications
is very important to understand.
React allows developers to use state at the component level by using
class-based components or functional-based components.

The Problem With State Management


Since component state can be passed around in props, it becomes
confusing quickly. For example, if you need to pass the state deep inside a
component tree to a child, you have to pass it through every component in
between. This is called prop-drilling, and it makes it increasingly difficult
to keep track of your state or modify any code in the future as it turns into
a tedious process.
To solve the problem of prop-drilling, developers working with React often
use some sort of state management tool. This is where many people
switch to Redux to manage state.
Getting started with Redux
To solve the problem of prop-drilling, developers working with React often
use some sort of state management tool. This is where many people
switch to Redux to manage state.
At first look, Redux seems complex and absolutely unnecessary. Some of
the questions many new developers have on their minds when learning
Redux are, “Why do I need to separate my state?” And, “What are all
these new terms and how did my folder structure become so messy?”
But once you understand the core concept behind Redux, it'll be the
solution for all state management problems.

Assessment: Quiz
The state management is there to maintain and store the user's information until the
session ends.

True False
Redux is the only state manager for React

True False
Prop drilling refers to the process of passing the props through the component tree to
deliver data to certain components.

True False

What is Redux
What is Redux?
By definition, Redux is a predictable state container for JavaScript apps.
In other words, Redux is a stand-alone library. It helps you write
applications that behave consistently, run in different environments
(client, server, and native), and are easy to test.
On top of that, it provides a great developer experience, such as live code
editing combined with a time-traveling debugger.
Principles of Redux
The predictability of Redux is determined by the three most important
principles as given below:

 Single Source of Truth: The state of your whole application is


stored in an object tree within a single store. As the whole
application state is stored in a single tree, it makes debugging easy,
and development faster.
 The state is Read-only: The only way to change the state is to
emit an action, an object describing what happened. This means
nobody can directly change the state of your application.
 Changes are made with pure functions: To specify how the
state tree is transformed by actions, you write pure reducers. A
reducer is a central place where state modification takes place.
Reducer is a function that takes state and action as arguments and
returns a newly updated state.
How Redux works?
To fully understand the Redux concept we first need to take a look at the
man building block. Redux has three main parts: Actions, Reducers, and
Store. Let’s explore what each one does:

 Actions: are used to send information from the application to the


store. Sending data to the store is needed to change the application
state after user interaction, internal events, or API calls.
 Reducers: are the most important building block and it’s important
to understand the concept.
 Store: The store is the central objects that holds the state of the
application.
To make it easy to understand, let's imagine this scenario, the component
triggers an action to change the value of the global state, The action gets
dispatched to the store. The store calls the reducer to create a new state
based on the dispatched action. When the new state is created the
component updates its view.

Assessment: Quiz
Redux is:

A library that is used to manage state. Can only be used with React. None
of the above .
By using Redux, we can deliver the data to any component without affecting the
other.

True False
By putting the data in a store, only the component with privileges can access it.

True False

Building block of Redux


What is an action?
Let’s dive deeper into the building blocks of Redux.
Actions are JavaScript objects as you can see in the following
example:
{

type: LOGIN_USER,

payload: {

username: 'sebastian',

password: '123456'

Here the action object has two properties:

 type: a constant to identify the type of action.


 payload: the object which is assigned to this property contains the
data which are sent to the store.

Action objects are created by using functions. These functions are called
action creators
function authUser(data) {

return {

type: LOGIN_USER,

payload: data,

};

Here you can see that the only purpose of an action creator
function is to return the action object as described.
Calling actions in the application is easy by using the dispatch
method:
dispatch(authUser(data));

What is a Reducer?
Reducers are the most important building block and it’s important to
understand the concept. Reducers are pure JavaScript functions that take
the current application state and an action object and return a new
application state:
const reducer = (state, action) => {

switch (action.type) {

case type1:

return; // the new state

case type2:

return; // the new state

default:

return state;

The important thing to notice here is that the state is not changed directly.
Instead a new state object (based on the old state) is created and the
update is done to the new state.

What is the Redux Store?


The store is the central objects that holds the state of the application. The
store is created by using the createStore method from the Redux library:
import { createStore } from ‘redux’;

let store = createStore(myReducer);

You need to pass in the reducer function as a parameter. Now you’re


ready to dispatch a action to the store which is handled by the reducer:

Redux data flow


The image below describes the Redux data flow and how every part gets
triggered:
Assessment: Quiz
The createStore function doesn't accept any parameter

True False
Reducers specify how the state changes:

True False
Choose the correct statements

The action creator dispatches actions to the store. The reducer receives a
previous state and an action and returns a new state. The view is the one
responsible for triggering the reducer.

The React-redux library


What is React-redux
React Redux is the official Redux UI binding library for React. If you're
using Redux and React together, you should also use React-Redux to bind
these two libraries.
As the official Redux binding for React, React-Redux is kept up-to-date
with any API changes from either library to ensure that your React
components behave as expected. Its intended usage adopts the design
principles of React - writing declarative components. The followings are
some benefits of using React-Redux library
 It Encourages Good React Architecture: As a general
architectural principle, we want to keep our own components
"unaware" of Redux. They should simply receive data and functions
as props, just like any other React component. This ultimately makes
it easier to test and reuse your own components.
 It Implements Performance Optimizations: React Redux
implements many performance optimizations internally, so that your
own component only re-renders when it actually needs to.
 Community Support: As the official binding library for React and
Redux, React Redux has a large community of users. This makes it
easier to ask for help, learn about best practices, use libraries that
build on top of React Redux, and reuse your knowledge across
different applications.

Redux vs react-redux
Redux gives you a store, and lets you keep states in it and extract them
out. It responds when the state changes. but that’s all it does.

It’s actually react-redux that lets you connect pieces of the state to React
components.

That’s right: redux knows nothing about React at all.

These libraries are like two peas in a pod, though. 99.999% of the time,
when anyone mentions “Redux” in the context of React, they are referring
to both of these libraries in tandem. So that's what you should keep in
mind when you see Redux mentioned on StackOverflow, Reddit or any
place else.

The redux library can be used outside of a React app too. It’ll work with
Vue, Angular, and even backend Node/Express apps.

Installing React-Redux
To start using Redux along with React, only you need to do is following
these steps:

1. Create a new react application


$ npx create-react-app react-redux-counter

2. Install redux
$ npm i redux

3. install react-redux
$ npm i react-redux
Redux folder architecture
Redux can make your life as a developer much easier or much harder
depending on the architecture that you follow.
Searching the web you can find a lot of architecture or different methods
to implement redux into your react application. The following is the one
that we recommend using it.

This architecture is simple and organized. You have to create a folder


called JS ( or any name that you prefer )
Under the JS folder, there will be four subfolders:
-> Actions: This folder will contain all the actions
-> Constants: This folder will include all the actions-creator
-> Reducers: it will hold the reducers
-> Store: it will contain the store creation.

Assessment: Quiz
To use Redux, we need:

Redux React-redux react


To use Redux with React, we need:

Redux react -redux react


To install react-redux, we run:
npm i redux npm i react-redux npm install --save react-redux

The Store
Create the store
The store is the one responsible for orchestrating the cogs. The store in
Redux is kind of magic and holds all the application's state.

Let's create a store to start playing with Redux. Under the store folder,
create a new file index.js,path to the file src/js/store/index.js, and
initialize the store.
// src/js/store/index.js

import { createStore } from "redux";

import rootReducer from "../reducers/rootReducer";

const store = createStore(rootReducer);

export default store;

As you can see, store is the result of calling createStore, a function from
the Redux library. createStore takes a reducer as the first argument and in
our case we passed in rootReducer (not yet present).
The most important concept to understand here is that the state in Redux
comes from reducers.

createStore function
createStore(reducer, [preloadedState], [enhancer])

Creates a Redux store that holds the complete state tree of your app.
There should only be a single store in your app.

Arguments:

1. Reducer: (Function): A reducing function that returns the next state


tree, given the current state tree and an action to handle.
2. [preloadedState]: The initial state. You may optionally specify it to
hydrate the state from the server in universal apps.
3. [enhancer]: The store enhancer. You may optionally specify it to
enhance the store with third-party capabilities such as middleware,
time travel, persistence, etc.

the arguments putted between [ ] mean that this arguments are optional.
The createStore function returns a store ( an object that holds the the
complete state of your application.

Fill in the blanks Solution


The createStore is imported from redux library. In order to work properly
the createStore function need at least one argument. This parameter is the reducer

The Reducer
Create a reducer
What’s a reducer?
A Redux reducer is just a JavaScript function. It takes two
parameters: the current state and action.

In a typical React component, the local state might be mutated in place. In


Redux you're not allowed to do that. The third principle of Redux (as
outlined by its creator) prescribes that the state is immutable and
cannot change in place.

In other words, the reducer must be pure. A pure function returns the
same output for the given input. Despite this terminology reasoning about
a reducer is not that hard.

Create a reducer
In our example we'll be creating a simple reducer which takes initial state
and action as parameters.
Create a new file under the folder Reducers named rootReducer.js.

src/JS/Reducers/rootReducer.js this is the path for the create file


const initialState = {

counter: 0

};

function rootReducer(state = initialState, action) {

return state;
};

export default rootReducer;

Assessment: Quiz
Reducer is a pure JavaScript function.

True False
The third principle of Redux prescribes that the state is immutable and cannot
change in place.

True False
A reducer only need an intialState parameter.

True False

The Actions
The need of actions
Redux reducers are without doubt the most important concept in Redux.
Reducers produce the state of an application.

But how does a reducer know when to generate the next state?

The second principle of Redux says the only way to change the state is by
sending a signal to the store. This signal is an action. So "dispatching an
action" means sending out a signal to the store.
The reassuring thing is that Redux actions are nothing more than
JavaScript objects. This is how an action looks like:
type: "INCREMENT_COUNTER",

payload: {

value: 1

The type property drives how the state should change and it's always
required by Redux. The payload property instead describes what should
change, and might be omitted if you don't have new data to save in the
store.

Create actions:
As a best practice in Redux we wrap every action within a function, so that
object creation is abstracted away. Such function takes the name of action
creator: let’s put everything together by creating a simple action creator.

In the directory Actions, create a file named actions.js


// src/Actions/actions.js

export const incrementCounter = (payload) => ({

type: "INCREMENT_COUNTER",

payload

});

Create actions
You can notice that the type property is a string. Strings are prone to
typos and duplicates and for this reason it's better to declare actions as
constants. Here come the role of the directory constants. Under this folder
create a new file actions-types.js
// src/js/constants/action-types.js

export const INCREMENT_COUNTER = "INCREMENT_COUNTER";

Now open up again src/js/Actions/actions.js and update the action to use


action types:
// src/Actions/actions.js

import { INCREMENT_COUNTER } from "../constants/actions-types";

export const incrementCounter = (payload) => ({

type: INCREMENT_COUNTER,

payload

Refactoring the reducer


When an action is dispatched, the store forwards a message (the action
object) to the reducer. At this point, the reducer checks the type of this
action. Then depending on the action type, the reducer produces the next
state eventually merging the action payload into the new state.

Let's fix our rootReducer.js

import { INCREMENT_COUNTER } from "../constants/actions-types";

const initialState = {

counter: 0

};

function rootReducer(state = initialState, action) {

switch (action.type) {

case INCREMENT_COUNTER:

return {

counter : state.counter + 1

return state;

};

export default rootReducer;

Fill in the blanks Solution


An action in redux is simply a JavaScript object that contains the type of this action
and the data which is called payload. The reducer receives the two pieces of
information and depending on the type, it decides how the state will be mutated.

Example
Example
During this skill, we are going to explore an example starting from scratch.
To see the big picture.
First, let’s start by creating our react application
$ npx create-react-app blog

Now let’s set the component tree, we are going to create a folder
component that contains the component we are using

under src/component creat these files PostList.js and CreatePost.js


PostList will receive the list of articles from the store and CreatePost.js will
add new posts into the store.
//PostList.js

import React from 'react'

const PostList = (props) => {

return (

<div>

{props.posts.map((post) => <div id={post.id}>

<h1>{post.title}</h1>

<p>{post.content}</p>

</div>)}

</div>

export default PostList

//CreatePost.js

import React, { useState } from 'react'

const CreatePost = () => {

const [title, setTitle] = useState('')

const [content, setContent] = useState('');


const handleSubmit = (e) => {

e.preventDefault()

return (

<form onSubmit={handleSubmit}>

<div>

<label htmlFor="Title">Title</label>

<input type="text" name="title" id="title" onChange={e


=> setTitle(e.target.value)} />

</div>

<div>

<label htmlFor="Content">Content:</label>

<textarea name="content" id="content" cols="30"


rows="10" onChange={e => setContent(e.target.value)} />

</div>

<div>

<input type="submit" value="Add" />

</div>

</form>

export default CreatePost

//App.js

import CreatePost from './Components/CreatePost';

import PostList from './Components/PostList';


function App() {

return (

<div className="App">

<CreatePost/>

<PostList/>

</div>

);

export default App;

Setup Redux
To start working with Redux, first, we start by installing react and react-
redux library
$ npm i redux react-redux

Then we are going to follow the architecture that we talked about in the
previous slides.
//src/JS/store.js

import { createStore } from 'redux'

import rootReducer from '../Reducers/rootReducer'

const store = createStore(rootReducer)

export default store;

//src/JS/Reducers/rootReducers.js

import { ADD_ARTICLE } from "../Constants/actions-types";

const initialState = {

posts: [
{

id: 1,

title: 'my first post',

content: 'my first content'

const rootReducer = (state = initialState, action) => {

switch (action.type) {

case ADD_ARTICLE:

return {

posts: [...state.posts, action.payload]

default:

return state

export default rootReducer

// src/JS/Constants/actions-types.js

export const ADD_ARTICLE = 'ADD_ARTICLE'

// src/JS/Actions/actions.js

import { ADD_ARTICLE } from "../Constants/actions-types";

export const addPost = newPost => {

return {

type: ADD_ARTICLE,

payload: newPost

}
}

Connect the store React application


To connect the store to your react application, you are going to need a
component from the react-redux library named Provider.
The provider component is used to wrap the react application and it will
give it access to the store.
To be sure that the application has access to the store, go ahead and
change the index.js of your react application like the following example:
//src/index.js

import React from 'react';

import ReactDOM from 'react-dom';

import './index.css';

import App from './App';

import { Provider } from 'react-redux';

import store from './JS/store';

ReactDOM.render(

<React.StrictMode>

<Provider store={store}> {/* the component Provider needs a props


store */}

<App />

</Provider>

</React.StrictMode>,

document.getElementById('root')

);

As you can see from the code above, the component Provider needs a props
named store, through this props we pass the redux store to the wrapped
hierarchy ( which in our case the whole App )

Connect the component to get the


state
In the previous slide, we saw how to make the store accessible for the
hierarchy. Every component in that hierarchy gets the right to connect and
use the data that exists in the Store. But this is not enough. The
component itself needs to be connected to the store.
The react-redux library provides us with another method connect. It
provides its connected component with the pieces of the data it needs
from the store, and the functions it can use to dispatch actions to the
store.
It does not modify the component passed to it; instead, it returns a new,
connected component class that wraps the component you passed in.
The syntax of the connect method might seem a little weird but let's take
a look at it.
connect(mapStateToProps, mapDispatchToProps)(Component)

Let's explain it now:

 mapStateToProps: it's a function that returns the state (or only a


portion of the state ) and passes it to the Component as a props. this
function is not provided by the library it needs to be implemented by
you.
 mapDispatchToProps: it does something similar, but for actions.
mapDispatchToProps connects Redux actions to React props. This
way a connected React component will be able to send messages to
the store.
 Component: The component that wish to connect to the store.

Let's take a look at the file PostList.js to better understand.


import React from 'react'

import { connect } from 'react-redux'

const mapStateToProps = state => {

return {

posts: state.posts

const PostList = (props) => {

return (

<div>

{props.posts.map((post) => <div id={post.id}>

<h1>{post.title}</h1>
<p>{post.content}</p>

</div>)}

</div>

export default connect(mapStateToProps)(PostList)

Handle Actions
The next step in our project is to make the component CreatePost work
and add the new posts to the store. To do so, we are going to use the
mapDispatchToProps function, like shown in the example below
import React, { useState } from 'react'

import { connect } from 'react-redux';

import { addPost } from '../JS/Actions/actions';

const mapDispatchToProps = dispatch => {

return {

addArticle: post => dispatch(addPost(post))

const CreatePost = (props) => {

const [title, setTitle] = useState('')

const [content, setContent] = useState('');

const handleSubmit = (e) => {

e.preventDefault()

props.addArticle({

id: Date.now(),

title,

content

})
}

return (

<form onSubmit={handleSubmit}>

<div>

<label htmlFor="Title">Title</label>

<input type="text" name="title" id="title" onChange={e


=> setTitle(e.target.value)} />

</div>

<div>

<label htmlFor="Content">Content:</label>

<textarea name="content" id="content" cols="30"


rows="10" onChange={e => setContent(e.target.value)} />

</div>

<div>

<input type="submit" value="Add" />

</div>

</form>

export default connect(null, mapDispatchToProps)(CreatePost)

The mapDispatchToProps is the second argument that the connect method


need so that's why we passed the null instead of mapSateToProps but
both methods can be passed if needed.

The function mapDispatchToProps takes as a parameter dispatch and returns


an object.
1. addAtricle : The key of the first element in the returned object. It's
the one that will be used in the component ( props.AddArticle )
2. function: That takes a post as an argument ( the new post to be
added ) and dispatch the action of adding that new post.

Go ahead and try this example for your own. You can find the whole
project at this link

Assessment: Quiz
The Provider component is imported from

redux react-redux react


Which functions are used to trigger an action in Redux?

trigger() connect() dispatch()


mapStateToProps and mapDispatchToProps are two methods defined by react-redux
library

True False

Redux Toolkit
What is Redux-toolkit?
React and Redux believed to be the best combo for managing state in
large-scale React applications. However, the configuration and the
enormously required boilerplate made it a little bit hard to understand and
manipulate.
Here came the role of the redux toolkit.
Redux-toolkit is a new way to implement Redux, a more functional way.
It's cleaner, you write fewer lines of code and we get the same Redux
state management, we have come to love and trust. The best part is it
comes with redux-thunk already built into it. Plus they use immerJs to handle
all the immutability, so all we need to think about is what needs to get
done.
Main features of Redux Tool Kit
The following function is used by Redux Took Kit, which is an abstract of
the existing Redux function. These function does not change the flow of
Redux but only streamline them in a more readable and manageable
manner.

 configureStore: Creates a Redux store instance like the original


createStore from Redux, but accepts a named options object and
sets up the Redux DevTools Extension automatically.
 createAction: Accepts an action type string and returns an action
creator function that uses that type.
 createReducer: Accepts an initial state value and a lookup table of
action types to reducer functions and creates a reducer that handles
all action types.
 createSlice: Accepts an initial state and a lookup table with reducer
names and functions and automatically generates action creator
functions, action type strings, and a reducer function.

You can use the above function to simplify the boilerplate code in Redux,
especially using the createAction and createReducer methods. However,
this can be further simplified using createSlice, which automatically
generates action creator and reducer functions.

What is so special about createSlice?


It is a helper function that generates a store slice. It takes the slice’s
name, the initial state, and the reducer function to return reducer, action
types, and action creators.
First, let's see how reducers and actions look like in traditional React-
Redux applications.

 Actions

import {GET_USERS,CREATE_USER,DELETE_USER} from "../constant/constants";

export const GetUsers = (data) => (dispatch) => {


dispatch({

type: GET_USERS,

payload: data,

});

};

export const CreateUser = (data) => (dispatch) => {

dispatch({

type: CREATE_USER,

payload: data,

});

};

export const DeleteUser = (data) => (dispatch) => {

dispatch({

type: DELETE_USER,

payload: data,

});

};

 Reducers

import {GET_USERS,CREATE_USER,DELETE_USER} from "../constant/constants";

const initialState = {

errorMessage: "",

loading: false,

users:[]

};

const UserReducer = (state = initialState, { payload }) => {

switch (type) {

case GET_USERS:

return { ...state, users: payload, loading: false };

case CREATE_USER:
return { ...state, users: [payload,...state.users],

loading: false };

case DELETE_USER:

return { ...state,

users: state.users.filter((user) => user.id !== payload.id),

, loading: false };

default:

return state;

};

export default UserReducer;

Now let's see how we can simplify and achieve the same functionality by
using createSlice.
import { createSlice } from '@reduxjs/toolkit';

export const initialState = {

users: [],

loading: false,

error: false,

};

const userSlice = createSlice({

name: 'user',

initialState,

reducers: {

getUser: (state, action) => {

state.users = action.payload;

state.loading = true;

state.error = false;

},

createUser: (state, action) => {

state.users.unshift(action.payload);
state.loading = false;

},

deleteUser: (state, action) => {

state.users.filter((user) => user.id !== action.payload.id);

state.loading = false;

},

},

});

export const { createUser, deleteUser, getUser } = userSlice.actions;

export default userSlice.reducer;

As you can see now all the actions and reducers are in a simple place
wherein a traditional redux application you need to manage every action
and its corresponding action inside the reducer. when
using createSlice you don’t need to use a switch to identify the action.
When it comes to mutating state, a typical Redux flow will throw errors
and you will require special JavaScript tactics like spread
operator and Object assign to overcome them. Since the Redux toolkit
uses Immer, you do not have to worry about mutating the state. Since a
slice creates the actions and reducers you can export them and use them
in your component and in Store to configure the Redux without having
separate files and directories for actions and reducers as below.
import { configureStore } from "@reduxjs/toolkit";

import userSlice from "./features/user/userSlice";

export default configureStore({

reducer: {

user: userSlice,

},

});

Fill in the blanks Solution


A basic createSlice methods takes in the following: name : which is name of the slice
for reference initialState : the initial state of the reducer reducers : contains all the
actions to mutate the reducer state
Middlewares
Advantages of Middleware

What is Middleware?
Redux middleware intermediates Action Creators and Reducers. The
Middleware intercepts the action object before a Reducer receives it and
gives it the functionality to perform additional actions or enhancements
with respect to the action dispatched.

Advantages of Middleware
Why use it?
The action/reducer pattern is very clean for updating the state within an
application. But what if we need to communicate with an external API? Or
what if we want to log all of the actions that are dispatched? We need a
way to run side effects without disrupting our action/reducer flow.

Middleware allows for side effects to be run without blocking state


updates.

We can run side effects (like API requests) in response to a specific action
or in response to every action that is dispatched (like logging). There can
be numerous Middlewares that an action passes through before ending in
a reducer.
Advantages of Middleware
The Redux middleware syntax is a mouthful: a middleware function is a
function that returns a function and that returns a function.

The first function takes the store as a parameter, the second takes
a next function as a parameter, and the third takes the action dispatched
as a parameter.
The store and action parameters are the current Redux store and the
action being dispatched. The real magic is found in the next() function.
The next() function is what you call to say "this middleware is done
executing, pass this action to the next middleware". In other words,
middleware can be asynchronous.
const reduxMiddleware = store => next => action => {

. . . . . .
next(action);

};

Logging action

Logging: one of the benefits of Redux is that it makes state changes predictable
and transparent. Every time an action is dispatched, the new state is computed
and saved. The state cannot change by itself, it can only change as a
consequence of a specific action.
Wouldn't it be nice if we logged every action that happens in the app, together
with the state computed after it? When something goes wrong, we can look back
at our log and figure out which action corrupted the state.

The logger function:


Middleware is applied in the state initialization stage with the enhancer
applyMiddlware()
import { createStore, applyMiddleware } from "redux";

Logger is the middleware function that will log action and state.
const logger = store => next => action => {

console.log('dispatching', action)

let result = next(action)

console.log('next state', store.getState())

return result

}
Now only modify the store.
const store = createStore(reducer, applyMiddleware(logger));

Assessment: Quiz
The middleware is placed between the action and the reducer.

True False
The applyMiddlewares() method is imported from react-redux.

True False
Asynchronous requests exist by default in Redux without the usage of middlewares.

True False

Redux thunk
What’s redux-thunk?
Thunk is another word for a function but it’s not just any old function. It’s a
special (and uncommon) name for a function that’s returned by another.
function wrapper_function() {

// this one is a "thunk" because it defers work for later:

return function thunk() {

// it can be named, or anonymous

console.log("do stuff now");

};

You already know this pattern. You just don’t call it “thunk.” If you want to
execute the “do stuff now” part, you have to call it like wrapper_function()
() – calling it twice, basically.

So how does this apply to Redux?


Well, by now, we know that Redux has a few main tools: there are
“actions”, “action creators”, “reducers”, and “middleware.”
Actions are just objects. As far as Redux is concerned, out of the box
actions must be plain objects, and they must have a type property. Aside
from that, they can contain whatever you want – anything you need to
describe the action you want to perform.
Actions look like this:
// 1. plain object

// 2. has a type

// 3. whatever else you want

type: "USER_LOGGED_IN",

userName: "dave"

Redux thunk:
Since it’s kind of annoying to write those objects by hand all the time (not
to mention error-prone), Redux has the option of “action creators” to
stamp these things out:
function userLoggedIn() {

return {

type: "USER_LOGGED_IN",

username: "dave"

};

It’s the same exact action, but now you can “create” it by calling the
userLoggedIn function. This just adds one layer of abstraction.

Instead of writing the action object yourself, you call the function, which
returns the object. If you need to dispatch the same action in multiple
places around your app, writing action creators will make your job easier.

Redux thunk:
Actually Redux action does nothing. They are nothing but objects. To make
them complete a concrete action (Calling an API, trigger another function
…) we have to make sure that the code lives inside a function. This
function (also called the thunk) is a bundle of work to be done. Right now
our action creator is performing an action. Like it’s shown in the example
below
function getUser() {
return function() {

return fetch("/current_user");

};

Redux thunk:
If only there was some way to teach Redux how to deal with functions as
actions.

Well, this is exactly what redux-thunk does: it is a middleware that looks at


every action that passes through the system, and if it’s a function, it calls
that function. That’s all it does.
The only thing I left out of that little code snippet is that Redux will pass
two arguments to thunk functions:
Dispatch, so that they can dispatch new actions if they need to;
getState, so they can access the current state.

Here’s an example to illustrate it:


function logOutUser() {

return function(dispatch, getState) {

return axios.post("/logout").then(function() {

// pretend we declared an action creator

// called 'userLoggedOut', and now we can dispatch it

dispatch(userLoggedOut());

});

};

the getState function can be useful for deciding whether to fetch new data
or return a cached result, depending on the current state.

Redux thunk:
Set up redux-thunk in your project.
If you have a project that already has Redux set up, adding redux-thunk
will be a two-step process.
First, install the package.
npm install --save redux-thunk
Then, wherever you have your Redux setup code, you need to import
redux-thunk and insert its middleware into Redux:
// You've probably already imported createStore from 'redux'

// You'll need to also import applyMiddleware

import { createStore, applyMiddleware } from "redux";

// Import the `thunk` middleware

import thunk from "redux-thunk";

// Import your existing root reducer here.

// Change this path to fit your setup!

import rootReducer from "./reducers/index";

// The last argument to createStore is the "store enhancer".

// Here we use applyMiddleware to create that based on

// the thunk middleware.

const store = createStore(rootReducer, applyMiddleware(thunk));

Just make sure you wrap thunk in the applyMiddleware call or else it won’t work.
After this, you’re all set: you can now dispatch functions that do whatever you
need them to.

Assessment: Quiz
The basic definition of thunk is that it is a function that returns another function.

True False
We can do an API call from a reducer.

True False
To install redux thunk, we need to run:

npm install --save redux-thunk npm i redux-thunk npm install --save redux

Redux with Hooks


Redux with Hooks
When React released the Hooks update, redux followed it by offering a set
of hook APIs as an alternative to the existing connect() Higher Order
Component. These APIs allow you to subscribe to the Redux store and
dispatch actions without having to wrap your components in connect().
These hooks were first added in v7.1.0.

Provider and create createStore


Provider” and “createStore()”: As with connect(), we should start by
wrapping our entire application in a <Provider> component to make the
store available throughout the component.
const store = createStore(rootReducer)

ReactDOM.render(

<Provider store={store}>

<App />

</Provider>,

document.getElementById('root')

useSelector()
mapStateToProps and connect argument:
We replace our famous mapStateToProps and connect argument with this
selector hook: useSelector() which allows us to extract data from the
Redux state store.

It will be called with the entire state of the Redux store as its only
argument.

It will be executed each time the function component is rendered (unless


its reference has not changed since the previous rendering of the
component which results in a set of cache that can be returned by the
hook without re-executing the selector).

useSelector() also subscribes to the Redux store and runs our selector
each time an action is sent.

With mapStateToProps, all individual fields are returned in a combined


object. It doesn't matter if the return object is a new reference or not.
connect () just compares the individual fields. With useSelector(), returning
a new object every time will always force a re-render by default. If you
want to retrieve multiple values from the store.

When using useSelector with an inline selector, a new instance of the


selector is created whenever the component is rendered.

This works as long as the selector does not maintain any state. However,
memoizing selectors (e.g. created via useSelector() from reselect) have an
internal state and that is why they must be used with care.
When the selector only depends on the state, ensure that it is declared
outside of the component so that the same selector instance is used for
each render.

useSelector(): exemple
Example : In the example below, we are going to use
the createSelector nad useSelector.
import React from "react";

import { useSelector } from "react-redux";

import { createSelector } from "reselect";

const selectNumOfDoneTodos = createSelector(

state => state.todos,

todos => todos.filter(todo => todo.isDone).length

);
export const DoneTodosCounter = () => {

const NumOfDoneTodos = useSelector(selectNumOfDoneTodos);

return <div>{NumOfDoneTodos}</div>;

};

export const App = () => {

return (

<>

<span>Number of done todos:</span>

<DoneTodosCounter />

</>

);

};

useDispatch()
mapDispatchToProps: This function is replaced by
a “useDispatch” function. This function returns a reference to the
dispatch function from the Redux store. We may use it to dispatch actions
as needed.
import React from "react";

import { useDispatch } from "react-redux";

export const CounterComponent = ({ value }) => {

const dispatch = useDispatch();

return (

<div>

<span>{value}</span>

<button onClick={() => dispatch({ type: "increment-counter" })}>


Increment counter

</button>

</div>

);

};

useCallback()
Pass an inline callback and an array of dependencies. useCallback will
return a memoized version of the callback that only changes if one of the
dependencies has changed.
This is useful when passing callbacks to optimized child components that
rely on reference equality to prevent unnecessary renders.
const memoizedCallback = useCallback(

() => {

doSomething(a, b);

},

[a, b],

);

Custom context
The <Provider> component allows us to specify an alternate context via the
context prop. This is useful if we’re building a complex reusable
component and we don't want our store to collide with any Redux store
our consumers' applications might use.

To access an alternate context via the hooks API, use the hook creator
functions:
import React from "react";

import {

Provider,

createStoreHook,

createDispatchHook,
createSelectorHook

} from "react-redux";

const MyContext = React.createContext(null);

// Export your custom hooks if you wish to use them in other files.

export const useStore = createStoreHook(MyContext);

export const useDispatch = createDispatchHook(MyContext);

export const useSelector = createSelectorHook(MyContext);

const myStore = createStore(rootReducer);

export function MyProvider({ children }) {

return (

<Provider context={MyContext} store={myStore}>

{children}

</Provider>

);

Assessment: Quiz
By using Redux hooks, we can ditch the connect function.

True False
useSelector() hook replaces the

mapStateToProps mapDispatchToProps
The hook that replaces mapDispatchToProps is

useDispatch() useDisptachToProps() dispatch()


Conclusion
Redux Recap
Do a victory dance cause you have made it this far!

After this Super Skill, we all agree that Redux is a very powerful tool when
it comes to state management.
However, understanding its architecture can be a little bit tricky but once
we understand it, it will make state management very easy and organized.
The main idea behind Redux is to centralize the data in one store. That
store will be managed via the reducers. These reducers are triggered via
an action which can be fired from a user interaction with the application.

The redux library also offers a sets of hooks that, can replace the old
structure using the class based architecture.

API
Understanding API
Introduction
Up until now, we have made incredible progess in frontend web
development and learned most of what there is to know. However, there is
one more thing that is necessary for our frontend application to
communicate with the backend server.

To make that communication happen, we use APIs. In this section, we are


going to see:

 What is an API?
 What are web services?
 What is the request/response approach?

Understanding API
What Is an API?
The term “API” stands for Application Programming Interface. If you break
that down word by word, you can get a pretty good grasp of what it
means.

An API is an interface that can be used to develop software that interacts


with an existing application.
In practice, an API is “a set of functions and procedures” that allows you to
access and build upon the data and functionality of an existing application.

Example
To describe the concept in further detail, we need to comprehend the
basics. Let’s start with the analogy of a restaurant menu. When we go to a
restaurant to eat, we choose from what is provided in the menu. At this
point, we convey our choices to the waiter. He/she then takes our order to
the chef who prepares our meal and our food arrives so we can enjoy a
nice meal. At this stage, it's only natural to ask ourselves: do we know
what the chef used to cook our fish or steak? How was it prepared? This
back-and-forth analogy serves as a starting point for our explanation.

Why? Because with an API, we really don’t know what’s going on behind
the scenes at the restaurant. All we really know is that we gave our order,
it was processed and out comes our dinner on a nice plate.

Let’s get back to the web development world. The API provides us with
data that we do not necessarily know how it has been created or served.

Assessment: Quiz
What does API stand for?
Application Programming Interface Application Progressive Interface
Asynchronous Post Interface
Google Maps' API is a private API.

True False
API only works with web applications.

True False

Web service
Introduction
A web service is a resource that is made available on the internet.
Therefore, web services, by definition, require a network.

The term “web service” is defined by W3C (the World Wide Web
Consortium), so it technically follows a whole host of standards.
To test web services, developers often use Postman.

To install Postman visit https://www.postman.com/

API and Web Services


An API defines the methods and instructions for one software program to
interact with another. When this action involves sending data over a
network, Web services come into the picture.
An API generally involves calling functions from within a software program.

Assessment: Quiz
A web service is

A React component. A resource that is made available on the internet.


Web services can only work with React.

True False
All Web services are APIs but not all APIs are Web services.

True False

Requests : Methods
Requests
We can imagine the web browser as the client and the computer
application that hosts a web site as the server.

Example: A client (browser) submits a HTTP request to the server then


the server returns a response to the client.
The response contains status information about the request and may also
contain the requested content.

Methods
The most-commonly-used HTTP verbs (or methods, as they are properly
called) are POST, GET, PUT, PATCH, and DELETE. These correspond to
create, read, update, and delete (or CRUD) operations. There are a
number of other verbs too, but they are used less frequently. One of those
methods are OPTIONS and HEAD. These are used more often than others.

POST

The POST method is used to send data from the client (browser)
to the server. As we can see in the example below, we used
Postman to enter the URL 127.0.01 on the port 3000 with a
POST method. The body of this request contains the email and
the password.

GET
In this example, we use the GET method to fetch data from the API.

PUT
PUT is used to update requests and to modify entries in the database. So,
generally PUT requests are sent with an ID as a query or a params and the
new data is shown in the body.
//id as query

http://localhost:3000/user/profile/?id=5e3bebed40dfda2656da1788

//id as params

http://localhost:3000/user/profile/5e3bebed40dfda2656da1788

PATCH

The HTTP PATCH request method applies partial modifications to a resource.


Unlike the PUT method that only allows complete replacements of a document.

Delete
In this example, we sent a request to delete the user and the method
DELETE is used with the ID 5e3bebed40dfda2656da1788

Conclusion
HTTP defines a set of request methods that indicate the wanted action to
be performed on a given resource. Even though they can be nouns, these
request methods are sometimes referred to as HTTP verbs, you could
check https://www.w3schools.com/tags/ref_httpmethods.asp.

Assessment: Quiz
We use PUT and PATCH to

Create a resource Read a resource Update a resource Delete a resource


When talking about requests, a browser is a

Client Server
The DELETE method needs a query or a parameter (like ID, or name ….) for it to
function.

True False

Response
Response: Introduction

HTTP Response is the packet of information that is sent by the server to the
client in response to an earlier Request (GET, POST, PUT ….) that was made by a
client. An HTTP Response contains the information requested by the client.

Status
HTTP response status codes indicate whether a specific HTTP request has
been successfully completed or not. Responses are grouped in five
classes:

1. Informational responses (100–199),


2. Successful responses (200–299),
3. Redirects (300–399),
4. Client errors (400–499),
5. Server errors (500–599).

What is the purpose of HTTP status codes?


HTTP status codes are standard response codes given by web site servers
on the internet. The codes help identify the cause of the problem when a
web page or other resource does not load properly.

Status: example
HTTP response status description:
The Status-Code element in a server response is a 3-digit integer where
the first digit of the Status-Code defines the class of response and the last
two digits do not have any categorization role. There are 5 values for the
first digit. Here is a table describing the existing status value.
In the table below, we find the most used response status.

Body

An HTTP message consists of a message header and an optional message


body, separated by a blank line, as illustrated above.

Body
Response Body contains the resource data that was requested by the
client.

In the example below, City Hyderabad was requested for the weather
data. If we take a look at the response body, it contains the city's weather
information. It also has information about Temperature, Humidity, Weather
description and more of the city's weather properties.
Response Body:

"City": "Hyderabad",

"Temperature": "25.7 Degree celsius",

"Humidity": "51 Percent",

"WeatherDescription": "haze",

"WindSpeed": "2.6 Km per hour",

"WindDirectionDegree": "120 Degree"

To summarize, an API needs to specify the responses for all API operations.
Each operation must have at least one response defined and it's usually a
successful response. A response is defined by its HTTP status code and the
data returned in the response's body and/or headers.

Assessment: Quiz
The HTTP message consists of a header and a body that are separated by a line.

True False
A GET request is sent to the server to retrieve a product. The request completed
successfully but the requested product does not exist in the database. The response
status code should be:

200 201 404 500


What is a Response Body?

Response Body contains the resource data that was requested by the client.
Response Body is all the packets of information that are sent by a server to a client.

Hands-on API : Overview


Intro
Since the beginning of this course, we were dealing with static data,
oftentimes hard-coded. But in real life applications, we need to pull data
from an external resource.
What if we want to handle data from an API? That's the purpose of this
section.

Specifically, we'll make use of the Fetch API and axios as examples for how
to request and use data.

Example APIs
ProgrammableWeb is a site that tracks more than 15,500 APIs. Google
Maps, Twitter, YouTube, Flickr and Amazon Product Advertising as some of
the most popular APIs. The following list contains several examples of
popular APIs:

1. Google Maps API: Google Maps APIs lets developers embed Google
Maps on webpages using a JavaScript or Flash interface. The Google
Maps API is designed to work on mobile devices and desktop
browsers. Link to API: Link

2. YouTube APIs: Google's APIs lets developers integrate YouTube


videos and functionality into websites or applications. It includes the
YouTube Analytics API, YouTube Data API, YouTube Live Streaming
API, YouTube Player APIs… link to youtube API: Link

3. Flickr API: The Flickr API is used by developers to access the Flick
photo sharing community data. The Flickr API consists of a set of
callable methods, and some API endpoints. Link to API: Link

4. Twitter APIs: Twitter offers two APIs.

o The REST API allows developers to access Twitter's core


data. Link
o The Search API provides methods for developers to interact
with Twitter Search and trends data.Link to APIs: Link
5. Amazon Product Advertising API: Amazon's Product Advertising API
gives developers access to Amazon's product selection and
discovery functionality to advertise Amazon products to monetize a
website. Link to API: Link

What is a base URL?

A base URL is basically the consistent part of your web address.

For example, you'll note that the address


section https://www.google.com/ always appears in the address bar.

This is the base URL. Everything that follows it is known as a URL path.
To find the base URL of your website, go to the site's front page. What you
see in the address bar on your site's front page is the base URL of your
website.

The base URL example


The following is an example of a well-formed REST URL:
https://284-RPR-133.mktorest.com/rest/v1/lead/318581.json?
fields=email,firstName,lastName

Which is composed of the following parts:

Base URL: https://284-RPR-133.mktorest.com/rest

Path: /v1/lead/

Resource: 318582.json

Query parameter: fields=email,firstName,lastName

Assessment: Quiz
The Twitter API helps developers to hack into twitter accounts.

True False
What is an URL base?

It’s the consistent part of a url It’s a type of an email address it‘s a module
used by React.
The query parameter is the parameter that is used after

"?" query= !!

Hands-on API : GET method


The GET request with browsers
Making an HTTP GET request is easy. Let's say you want to visit
gomycode.co in your browser. All you need to do is launch your browser
and enter the address: https://www.gomycode.co

What’s fetch?
To fetch data from an API, we can use the JavaScript fetch method. We can
also use an external library like axios, request, superagent, supertest and
many others.
In this Super Skill, we are going to use the fetch method.

The fetch method is provided by web APIs and it’s supported by almost all
the new browser versions.

PS. There is no need to install anything.

In this part, we are going to get the list of courses from algolia API on
Redux.
"https://hn.algolia.com/api/v1/search?query=redux"

The GET request with React.


In this step, we are going to create our React project in the App.js. What
we are going to need is:

1. A state to set the returned values from the API.


2. A state to handle the error (if there is any).
3. useEffect hook on the API after the component mounts.
import React, { useEffect, useState } from "react";

const App = () => {

const [data, setData] = useState();// where to store the returned data

const [error, setError] = useState(null);// where to store the coming


errors

useEffect(() => {

function fetchData() {// the function to fetch data from the api

fetch("https://hn.algolia.com/api/v1/search?query=redux")

.then(res => res.json())

.then(res => setData(res))

.catch(err => setError(err));

fetchData();

}, []);

return <div />;

};

export default App;

The GET request with React.


Well let’s explain some concepts first. When we send a request to an API,
it will take some time to find the needed data from its resources and
return exactly what we want. Therefore, JavaScript will not block the rest
of the operation but it will continue executing the rest of the program and
when the API gives us a result of our request, JavaScript will handle it then.
This is the asynchronous approach in JavaScript, we will see it in more
detail in other super skills.
For the time being, JavaScript gives us the .then() .catch() methods to
deal with asynchronous functions.
In simpler terms, when calling an API, we tell the browser that the
response will take some time so it can go continuing its work and it will
notify us when the response gets back.
function fetchData() {// the function to fetch data from the api
fetch("https://hn.algolia.com/api/v1/search?query=redux")

.then(res => res.json())// when the result comes back with


success here is what to do

.then(res => setData(res))

.catch(err => setError(err));// if there is an error here what


you have to do.

The GET request with React.


If we perform a console.log to the data state, we will receive the following
result:

It contains an array of objects named hits. This is what we are going to


show to users.

The GET request with React.


If we perform a console.log to the data state, we will receive the following
result:
import React, { useEffect, useState } from "react";

const App = () => {

const [data, setData] = useState([]); // where to store the returned


data

const [error, setError] = useState(null); // where to store the coming


errors
useEffect(() => {

function fetchData() {

// the function to fetch data from the api

fetch("https://hn.algolia.com/api/v1/search?query=redux")

.then(res => res.json()) // when the result comes back with


success here is what to do

.then(res => setData(res.hits))

.catch(err => setError(err)); // if there is an error here what


you have to do.

fetchData();

}, []);

return (

<div>

<ul>

{data.map(course => (

<li>

<a href={course.url}> {course.title}</a>

</li>

))}

</ul>

</div>

);

};

export default App;


Output

The GET request with React: JSON


If we paste the URL of the API in the browser, we will get a result like this
one:
This representation is called a JSON format. That’s the result the API is
sending to our application.

What’s JSON?
JSON (JavaScript Object Notation) is the most widely used data format for
data interchange on the web. This data interchange can happen between
two computer applications at different geographical locations or running
within the same machine.

The good thing is that JSON is a format that's understandable by both


humans and machines. So while applications/libraries can parse the JSON
data – humans can also look at data and derive meaning from it.
A JSON document may contain text, curly braces, square brackets, colons,
commas, double quotes, and maybe a few other characters.

Primarily, JSON is built on two structures:

1. A collection of name/value pairs. In various languages, this is


realized as an object, record, structure, dictionary, hash table, keyed
list, or an associative array.
2. An ordered list of values. In most languages, this is realized as an
array, vector, list, or sequence.

Assessment: Quiz
The fetch method can be used after installing the fetch API module.

True False
What is true about JSON?
JSON is a data format for data interchange on the web JSON is a human and
machine readable format JSON is a programming language JSON is a React
library JSON is built in a structure of collection of name/value pairs.
The JSON document can contain methods.

True False

Hands-on API : POST with React


POST with React.
The fetch API also gives us the ability to post data to the API.
function postData() {

// the function to post data to the api

fetch("https://jsonplaceholder.typicode.com/users", {

method: "POST", //setting the method

headers: {

Accept: "application/json",

"Content-Type": "application/json"

},//setting the header

body: JSON.stringify(user)//setting the body

})

.then(res => res.json())

.then(res => setData(res))

.catch(err => setError(err));

In the example above we gonna add user in the


Api "https://jsonplaceholder.typicode.com/users", we gonna use Post
Method

POST with React.


In this code below, we have added an input for the name. If we click add, it
will add a user inside the API.
const App = () => {

const [user, setUser] = useState();

const handleSubmit = e => {

e.preventDefault();

fetch("https://jsonplaceholder.typicode.com/users", {

method: "POST",

headers: {

Accept: "application/json",

"Content-Type": "application/json"

},

body: JSON.stringify(user)

})

.then(res => res.json())

.then(res => console.log(res))

.catch(err => console.log(err));

};

const handleChange = e =>

setUser({ id: Date.now(), [e.target.name]: e.target.value });

return (

<div>

<form onSubmit={handleSubmit}>

<label>

Person Name:

<input type="text" name="name" onChange={handleChange} />

</label>

<button type="submit">Add</button>

</form>
</div>

);

};

export default App;

Assessment: Quiz
The first argument in the POST method is:

The data The path The config


The POST request method expects a second parameter.

True False
The data sent in the request body should only be an object.

True False

API with axios


What’s Axios?
Axios is a promise based HTTP client for the browser and Node.js.
By using Axios it’s easy to send asynchronous HTTP request to REST
endpoints and perform CRUD operations. The Axios library can be used in
your plain JavaScript application or can be used together with more
advanced frameworks like React.js
There are some difference between axios the fetch web API:
Syntax: the http request using axios is more simple than using fetch
Support: the fetch web API is not supported by all the browser, on the
other hand axios is supported even by the old browser version (like IE)
Response timeout: the timeout set up is much easier using axois than
using the fetch API.

Install Axios
To install axios we simply run the following command:
npm i axios

// or

npm install axios

Use Axios
Axios syntax is mostly like the fetch API.
To Perform a get request:
// Make a request for a user with a given ID

axios.get('/user?ID=12345')

.then(function (response) {

// handle success

console.log(response);

})

.catch(function (error) {

// handle error

console.log(error);

})

Posting Data using Axios


The post request syntax is the following:
axios.post(url, data,config)
 Url: the url of the api
 Data: the data to be sent (optional field)
 Config: the header configuration (optional field)

axios

.post("/user", {

firstName: "Fred",

lastName: "Flintstone"

})

.then(function(response) {

console.log(response);

})

.catch(function(error) {

console.log(error);

});

Chaining request
Axios comes with build in feature which gives us the ability to send
multiple requests.
const requestOne =
axios.get("https://api.storyblok.com/v1/cdn/stories/health?
version=published&token=wANpEQEsMYGOwLxwXQ76Ggtt");

const requestTwo =
axios.get(https://api.storyblok.com/v1/cdn/datasources/?
token=wANpEQEsMYGOwLxwXQ76Ggtt");

const requestThree =
axios.get("https://api.storyblok.com/v1/cdn/stories/vue?
version=published&token=wANpEQEsMYGOwLxwXQ76Ggtt");

axios

.all([requestOne, requestTwo, requestThree])

.then(axios.spread((firstResponse, secondResponse, thirdResponse) => {

console.log(firstResponse.data,secondResponse.data,
thirdResponse.data);
})

.catch(errors => {

console.error(errors);

});

Assessment: Quiz
Axios is promise base handler

True False
Axios is built in module with Node.js

True False
The third parameter in the post method is mandatory

True False

Hands-on API : Headers


Headers:
HTTP header fields are components of the header section of request and
response messages in the HTTP Protocol. They define the operating
parameters of an HTTP transaction.
//example of headers using postman

'content-type': 'application/x-www-form-urlencoded',

'user-agent': 'PostmanRuntime/7.22.0',

accept: '*/*',

'cache-control': 'no-cache',

'postman-token': '35f27261-d4da-47d7-b540-9216d4fa694e',

host: '127.0.0.1:3001',

'accept-encoding': 'gzip, deflate, br',


'content-length': '37',

connection: 'keep-alive'

Headers:
The REST headers and parameters contain a wealth of information that
can help you track down issues when you encounter them. HTTP Headers
are an important part of the API request and response as they represent
the meta-data associated with the API request and response. Headers
carry information for:

1. Request and Response Body


2. Request Authorization
3. Response Caching
4. Response Cookies

Other than the above categories HTTP headers also carry a lot of other
information around HTTP connection types, proxies etc. Most of these
headers are for management of connections between client, server and
proxies and do not require explicit validation through testing.

Headers:
Headers are mostly classified as request headers and response headers,
know the major request and response headers. You will have to set the
request headers when you are sending the request for testing an API and
you will have to set the assertion against the response headers to ensure
that right headers are being returned.

The headers that you will encounter the most during API testing are the
following, you may need to set values for these or set assertions against
these headers to ensure that they convey the right information and
everything works fine in the API:

Authorization: Carries credentials containing the authentication


information of the client for the resource being requested.

WWW-Authenticate: This is sent by the server if it needs a form of


authentication before it can respond with the actual resource being
requested. Often sent along with a response code of 401, which means
‘unauthorized’.

Accept-Charset: This is a header which is set with the request and tells
the server about which character sets are acceptable by the client.
Content-Type: Indicates the media type (text/html or text/JSON) of the
response sent to the client by the server, this will help the client in
processing the response body correctly.

Cache-Control: This is the cache policy defined by the server for this
response, a cached response can be stored by the client and re-used till
the time defined by the Cache-Control header.

Headers:

The HTTP Header contains information about the HTTP Body and the
Request/Response.
Information about the body is related to the content of the Body such as the
length of the content inside the body.
The information about Request/Response is the general information about the
request/response and it is not specific to the content of the body, example at
what time the Request was made
The properties in header are specified as name-value pair which are separated
from each other by a colon ‘:’, (example name:value)

Headers:
Request Header: is present when you make a request to the server, it
contains information about the request such as the URL that you have
requested, the method(GET, POST, HEAD) ,the browser used to generate
the request and other info.

Example
User-Agent:”Mozilla/5.0 (Windows NT 10.0; WOW64; rv:41.0) Gecko/20100101
Firefox/41.0″

The term browser is also called user-Agent. So even a simple request to a


page involves sending the information about your browser and the
operating system you are using. You can see from the above Header field
that we are using Windows 10 and Firefox 41.0 browser.

Response Header: is sent from the server after the user sends a request
for a particular page or resource and it contains information such as the
encoding used in the content, the server software that is used on the
server machine to generate the response and other information.

Most of the sites usually hide their server information in order to make it
hard for hackers to know which software is being used on the server.

Assessment: Quiz
The http header of a request contain information about the server

True False
The authorization exists in the request body

True False
Http header contain information about the body

True False

Conclusion
API Recap

In the image above, you can see the relationship between the front-end
and the backend and how they communicate with each other.
During all the previous super skills, we have learned how to build a front-
end application. The API is the intermediate between the front-end and the
backend server
Let’s practice more with the checkpoint.
Right now, we are ready to work with external API, to make our application
consume external resources, and to interact with these resources. Let’s
practice more with the checkpoint.

You might also like