Full React js
Full React js
Namaste React
Episode 01 - Inception
What is a CDN ?
Aditya Kharadkar
3
React.development.js
React-dom.development.js
● Using this file, React interacts with the browser DOM.
Aditya Kharadkar
4
● The costliest operation for a browser is when the browser needs
to manipulate the DOM.
● Any React element is nothing but a JavaScript object.
● This object contains a key known aspropswhich storesthe
children and other attributes of the React element in a key-value
pair.
● The render() function is responsible for taking the JavaScript
object (React element) as an argument, converting it into an
HTML tag and putting it in the DOM.
Aditya Kharadkar
5
● The reason it was recommended to put <script> tags at the end of
the <body> was so that the scripts wouldn’t stop the browser
from parsing the HTML.
● When a browser gets to a <script> tag, it stops everything else
and loads the files for that <script> tag and then evaluates it.
● Thus, if you put <script> tag in the <head> or at the beginning of
the <body>, then the user would have to wait longer for the HTML
to render, possibly leaving them staring at a blank page for a
while.
● Nowadays this isn’t really a concern any more because you can
force the browser to download/evaluate JS files asynchronously
by using the async/defer attribute on the <script> tag.
● Be advised, these attributes only work for <script> tags loading
external JS files (i.e. thesrcattribute is pointingto a file).
Aditya Kharadkar
6
● If there is already an HTML element in the <div> tag, then that
HTML element will be loaded in the DOM and shown on the page.
● But as soon as JavaScript reaches the <script> tag which imports
the React code, it will replace that HTML element with the React
code.
What is Emmet ?
● Emmet is a free add-on for your text editor that allows you to
type shortcuts that are then expanded into a full piece of code.
1. Library
a. A library provides a set of helper
functions/objects/modules which your application code calls
for specific functionality.
Aditya Kharadkar
7
Aditya Kharadkar
8
Aditya Kharadkar
9
When does React sync the changes of Virtual DOM with Real DOM
?
● React synchronizes the changes from the virtual DOM to the Real
DOM during a process called reconciliation. This process involves
several steps:
○ State and prop changes
○ Re-rendering
○ Diffing - React compares the new virtual DOM tree with the
previous one to identify what has changed.
○ Batch updates - React doesn’t immediately update the Real
DOM with each change. Instead, it batches updates to
optimize performance. The batching happens within the
lifecycle of an event or after a certain period of time. (e.g.,
after user action like clicking a button or typing in an input
field).
○ Commit phase.
○ Asynchronous updates.
Aditya Kharadkar
10
● Async
○ Execution order- Scripts with async attributes are
executed as soon as they are downloaded regardless of the
order in which they appear on the document.
○ Loading behavior- The browser will download the scriptin
the background while continuing to parse the HTML
document. Once the script is downloaded, it will immediately
execute, potentially interrupting the parsing of the
document.
○ Use case- Best for scripts that are independent anddo not
rely on the DOM being fully parsed or other scripts being
loaded.
● Defer
○ Execution order- Scripts with defer attribute are
executed in the order they appear in the document, but only
after the entire HTML document has been parsed.
○ Loading behavior- The browser will download the scriptsin
the background while parsing the HTML document, but will
defer execution of the script until after the HTML parsing
is complete.
○ Use case- Ideal for scripts that need to interactwith fully
parsed DOM or that depend on other scripts.
Aditya Kharadkar
11
What is NPM ?
Aditya Kharadkar
12
● It is the manifest file of any node.js project and contains the
metadata of the project.
● This metadata information can be categorized into below
categories:
○ Identifying metadata properties:It basically consistsof
the properties to identify module/project such as the name
of the project, current version of the module, license,
author of the project, description about the project, etc.
○ Functional metadata properties:It consists of the
functional values/properties of the project/module such as
entry/starting point of the module, dependencies in project
scripts being used, repository link, etc.
What is a bundler ?
● A JavaScript bundler is a tool that puts your code and all its
dependencies together in one JavaScript file.
● It is a development tool that combines many JavaScript code
files into a single one that is production-ready loadable in the
browser.
● Following are the top 5 bundlers in JavaScript:
○ Browserify
○ ESbuild
○ Parcel
○ Rollup
○ Webpack
Aditya Kharadkar
13
Aditya Kharadkar
14
● When you install or update packages using npm, it checks the
package-lock.json file to ensure the specified versions are
installed.
● This lockfile is especially important when collaborating on
projects as it guarantees that all the contributors use consistent
package versions.
Transitive Dependencies
Aditya Kharadkar
15
Explain NPM
Aditya Kharadkar
16
Explain NPX
Aditya Kharadkar
17
■ For example, you can use ‘npx parcel index.html’ to run
parcel without needing to install it globally.
Why should CDN links not be used to bring React and React-dom in
the project ?
● If we use CDN links, then we will have to make a network call to
bring React into our project.
● Currently we use React version 18 which is mentioned in the CDN
link as well. So if in future, React version 19 comes, then we will
have to change the CDN links again.
● We can install React using npm install react which will store React
into node modules and will not cause any dependency issues.
● To get React from a CDN link, you will need to have a network
(internet) connection.
● When we install React into the application and remove the CDN
links, then we will get an error which saysUncaught
ReferenceError: React is not defined.
● This happens because we have installed React, but not imported it
into our JavaScript file.
Aditya Kharadkar
18
Aditya Kharadkar
19
How does parcel know that there are changes in the file/code ?
● Parcel uses a file watching algorithm which is developed using C++.
● This algorithm keeps track of every file and every change made
into a file.
● When we start the server using parcel for the first time, it
creates a folder in the project named.parcel-cache.
● So the parcel uses caching. And after every subsequent build, it
will update the cache.
● Inside package.json, there is a key named “main” which has a value
i.e.file_name(App.js).
● This tells npm that App.js is the entry point.
Aditya Kharadkar
20
● But since we use the parcel, we give an entry point, we get an
entry point while executing the command itself. So in that case,
this ‘main’ key is of no use.
● When we try to execute ‘npx parcel build index.html’, then it gives
an error. Because, the entry point given in the command has a
conflict with the value of ‘main’ key.
● So in that case, we should remove the ‘main’ key-value pair from
package.json.
● To make our app compatible with older/specific browsers, we can
make use ofbrowserslist.
● In the package.json file, we can create a list and give it name as
browserslistand specify all the browsers/specificversions in the
list.
Aditya Kharadkar
21
Aditya Kharadkar
22
● Currently we use below commands to create a dev and prod build
○ npx parcel index.html
○ npx parcel build index.html
● Instead we can add these commands into the scripts in the
package.json file.
JSX
● JSX is a syntax extension for JavaScript that lets you write
HTML-like markup inside a JavaScript file.
● The syntax is used by preprocessors (i.e. transpilers like babel) to
transform HTML like syntax into standard JavaScript objects
that a JavaScript engine will parse.
Aditya Kharadkar
23
Babel
Component composition
Aditya Kharadkar
24
Note: The code is readable because we write JSX. If the code is
readable, that does not mean React is making it readable. JSX is the
one which helps to achieve it.
Aditya Kharadkar
25
Aditya Kharadkar
26
Reconciliation in React
● The React reconciliation process is the engine behind its efficient
updates.
● When the state of a component changes, React needs to
determine what updates are necessary to the Real DOM, which is
where the reconciliation process comes into play.
● Reconciliation is React’s way of diffing the virtual DOM tree with
the updated virtual DOM to determine the most efficient way to
update the real DOM.
● This process allows React to apply only the necessary changes to
the DOM, avoiding the costly operation of updating the entire
DOM tree.
● The reconciliation algorithm is designed to optimize this process,
ensuring that the minimum number of operations are performed
leading to potential performance.
Aditya Kharadkar
27
● Keys help React identify which items have changed, are added or
are removed.
● Keys should be given to the elements inside the array to give the
elements a stable identity.
Aditya Kharadkar
28
● This can negatively impact the performance and may cause issues
with component state.
● If you choose not to assign any explicit key to list items, then
React will default to using indexes as keys.
Aditya Kharadkar
29
Can we have both named and default exports in the same file ?
● You can use one or both of them in the same file.
● A file can have no more than one default export, it can have as
many named exports as you like.
React Hooks
Diff Algorithm
Aditya Kharadkar
30
Aditya Kharadkar
31
Microservices Architecture
Aditya Kharadkar
32
Aditya Kharadkar
33
● CORS is an HTTP header based mechanism that allows a server to
indicate any origins (domain, scheme, or port) other than its own
from which a browser should permit loading resources.
● CORS also relies on a mechanism by which browsers make a
‘preflight’ request to a server hosting the cross-origin resource,
in order to check that the server will permit the actual request.
● An example of cross-origin request: The frontend JavaScript
code served fromhttps://domain-a.comuses fetch tomake a
request forhttps://domain-b.com/data.json.
● For security reasons, browsers restrict cross-origin HTTP
requests initiated from scripts.
● For example, fetch() and XMLHttpRequest follow the same origin
policy.
● That means a web application using those can only request
resources from the same origin the application was loaded from
unless the response from other origins includes the right CORS
headers.
Note - Showing the spinner until the data is fetched on the screen is
not a good practice.
Aditya Kharadkar
34
Shimmer UI
● When the page loads and the data is being fetched, until the data
is displayed on the UI, instead of showing a spinner, we can show
the skeleton of the UI.
● The useEffect() is used to handle the side effects such as
fetching data and updating the DOM.
● This hook runs on every render but there is also a way of using a
dependency array using which we can control the effect of
rendering.
● It is used to mimic the lifecycle methods of class-based
components.
● The motivation behind the introduction of useEffect is to
eliminate the side effects of using class-based components.
Aditya Kharadkar
35
● For example, tasks like updating the DOM, fetching data from
API endpoints, setting up subscriptions or timers, etc can lead to
unwanted side effects.
● How does it work ?
○ You call useEffect with a callback function that contains the
side effect logic.
○ By default, this function runs after every render of the
component.
○ You can optionally provide a dependency array as the second
argument.
○ The effect will only run again if any of the values in the
dependency array changes.
Aditya Kharadkar
36
Aditya Kharadkar
37
Routing in React
Aditya Kharadkar
38
● Example:
● But just creating the configuration is not enough. We will have to
provide this configuration to render it on to the page.
● To do that, we useRouterProviderwhich will providethe routing
configuration to the app.
● Example:
● We also need a component which will be shown whenever a user
tries to access an anonymous path.
Aditya Kharadkar
39
● Now we have to show the respective component based on its path
in the <AppLayout /> component.
● To help us to do that, react-router-dom provides anoutlet.
● This outlet gets filled with children when the user tries to access
a path and shows that component on the UI based on that path.
Aditya Kharadkar
40
Aditya Kharadkar
41
Dynamic routing
● It will display the result of calling the useState() function in our
browser’s developer console.
● const [count, setCount] = useState(0); ->[0, function]<- output
Aditya Kharadkar
42
What are various ways to add images into our app ? Explain with
code examples.
Aditya Kharadkar
43
Aditya Kharadkar
44
Aditya Kharadkar
45
● So we can say that super() is a reference to the parent class
constructor i.e.React.Component.
● In the above example, React.Component is also the base class of
UserClass component.
● So when we pass props to super(), the props get assigned tothis
also.
● So to conclude, if we want to usethis.props, or simplythis
keyword inside the constructor, we need to pass the props coming
from the parent class (React.Component) in super.
Aditya Kharadkar
46
Aditya Kharadkar
47
● If we have two state variables, and we try to update only one,
then React will update only that state variable and it will not
touch the other one.
Aditya Kharadkar
48
Aditya Kharadkar
49
Constructor (Parent) -> render (Parent) -> Constructor (Child) -> render
(Child) -> componentDidMount (Child) -> componentDidMount(Parent)
Aditya Kharadkar
50
CreateHashRouter
CreateMemoryRouter
Aditya Kharadkar
51
● In React, the useEffect hook is designed to handle the side
effects in functional components.
● It’s a powerful and flexible tool for managing asynchronous
operations, such as data fetching, API calls and more.
● However, useEffect itself cannot directly accept an async
callback function.
● This is because useEffect expects its callback function to return
either nothing i.e.undefinedor a cleanup function,and it doesn’t
work well with promises returned from the async functions.
● There are a few reasons for this:
a. Return value expectation
■ The primary purpose of the useEffect callback
function is to handle side effects and perform cleanup.
■ React expects us to return either nothing i.e.
undefined from the callback or return a cleanup
function.
■ An async function returns a promise, and it doesn’t fit
well with this expected behavior.
b. Execution order and timing
■ With async functions, we might not have fine-grained
control over the execution order of the asynchronous
code and cleanup code.
■ React relies on the returned cleanup function to
handle cleanup when the component is unmounted or
when the dependencies specified in the useEffect
dependency array change.
Aditya Kharadkar
52
■ If you return a promise, React doesn’t know when or
how to handle the cleanup.
Aditya Kharadkar
53
● If we have a function, a class, or a single entity in our app, it
should have a single responsibility.
● For example, <Header> component in our app should have only one
responsibility i.e. to display the header on the application.
● If we have a component which is doing multiple things, then we
should divide that component into multiple components where
each one of them has a single responsibility.
● Breaking down the code into small modules ->Modularity
Aditya Kharadkar
54
Aditya Kharadkar
55
We can have this component only to display the data on the web page
and can create a custom hook which fetches the data.
Aditya Kharadkar
56
Home Component
● In the above example, I have moved the logic of fetching data
into a custom hook i.e.useDemo.
● Then I imported the custom hook useDemo into the Home
component and used destructuring to get the itemDetails which is
returned from the useDemo() hook.
● Because of this, my Home component only has one responsibility
which is to display the data.
● The Home Component became clean since all the logic of fetching
data is now moved into the custom hook.
Aditya Kharadkar
57
The above hook checks if the user is online or offline using the window
object and the callback function sets the value of isOnline and the hook
then returns the value.
Aditya Kharadkar
58
● It is a naming convention for custom hooks which is followed by
most of the companies.
● A lot of companies use a linter which throws an error if the
custom hooks are not named like this.
● It is a good practice to use the wordusewhile namingthe custom
hook.
● If someone else sees the code, they will get to know that this is
not a normal function but a React hook.
Having a single bundle will make our app slower since a single bundle will
contain all the code of the application which takes a lot of time to load.
The solution for this is to split our app into smaller chunks (bundles).
This process is known as below terms:
1. Chunking
2. Code Splitting
3. Dynamic Bundling
4. Lazy Loading
5. On demand loading
Aditya Kharadkar
59
This bundle will not be loaded initially. It will be loaded only when the
user visits the cart page.
That means, with this approach the app will have 2 bundles. One would
be a normal bundle which contains all the code of the app except for
the cart component. This bundle will be loaded when the user visits our
app.
The other bundle will contain the code of the cart component which will
be loaded only when the user visits the shopping cart.
Aditya Kharadkar
60
1. Reduces the initial load time by reducing the bundle size.
2. Reduces browser workload.
3. Improves application performance in low-band width situations.
4. Improves user experience at initial loading.
5. Optimizes resource usage.
Example
Aditya Kharadkar
61
Suspense
● Suspense is best used when you want to display a fallback while
waiting for something to load.
● The two main use cases for this are when you are waiting for data
to be fetched from an API after the initial page load and when
you are lazy loading other React components.
Aditya Kharadkar
62
// Better approach -> create an object which contains all the
// styles and then assign it to the style attribute
Aditya Kharadkar
63
Aditya Kharadkar
64
● Create a component and assign a styled property to it. Note the
use of template literals denoted by backticks in the wrapper
object.
Aditya Kharadkar
65
Conditional Styling
Aditya Kharadkar
66
Aditya Kharadkar
67
5. Run your build process with npm run dev or whatever command is
configured in your package.json file.
6. Make sure your compiled css is included in thehead.
Aditya Kharadkar
68
In tailwind.config.js, what does all the keys mean (content, theme,
extend, plugins)?
The .postcssrc file (or postcss.config.js file in some setups) is used to
configure PostCSS, a tool for transforming CSS with JavaScript
plugins. PostCSS is often used in conjunction with Tailwind CSS to
enable additional CSS processing capabilities. Here’s why you might
have a .postcssrc file:
Aditya Kharadkar
69
Aditya Kharadkar
70
Aditya Kharadkar
71
1.Uncontrolled Components
a. If a component is managing its own state and controlling the
behavior on its own then the component will be known as
Uncontrolled component.
b. The parent component will have no power or control over
this component and hence it will be known as an uncontrolled
component.
c. In the above example, the <ItemCard /> component is a child
component of the <ItemCardList /> component.
Aditya Kharadkar
72
b. In the above example, the <ItemCard /> component does not
have any state variable to manage.
Aditya Kharadkar
73
● In the above example, the <ItemCard /> component does not
control its own state, instead it is controlled by its parent
component <ItemCardList />.
● But with the currently implemented code, we can not change the
state by clicking the button because the parent component has no
way to know about the user's interaction with the button.
● To do that, we need to let the parent component know when the
button is clicked so that it can change the value of the state
variable i.e.showHeading.
● This can be achieved bylifting the state up.
● In the below example, we pass a function as a prop i.e.onShowto
the child component i.e. <ItemCard /> from the parent component
i.e. <ItemCardList /> which sets the value of the state variable
showHeading.
● In the child component, we use theonShowprop andpass it as a
function to the onClick event in the button element.
● This will let the parent component know that the user has clicked
the button. Then the value of theshowHeadingstatevariable will
be changed.
Aditya Kharadkar
74
Note - React has a one-way data stream. That means the data flows
into one direction i.e. from parent component to child component.
Props Drilling
● Passing props is a great way to explicitly pipe data through your
UI tree to the components that use it.
● But passing props can become inconvenient when there is a huge
tree of components which has a parent component having children
Aditya Kharadkar
75
Aditya Kharadkar
76
● In the above code, the CartContext is imported in the <App />
component and is being used as a wrapper of the <Header /> and
<Body /> component.
● This will make the context available to access for the application.
Aditya Kharadkar
77
Aditya Kharadkar
78
Aditya Kharadkar
79
Introduction
Redux and React both are not the same thing. Redux is not part of
React. They both are different libraries.
All the applications built using Redux can also be built without using it.
Redux is not the only library for state management. There is also
another library namedZustand.
Just like we have React Dev Tools, we also have Redux Dev Tools which
help us to debug our application when we use Redux.
Redux Storeis like a very big JavaScript object,which has a lot of
data in it, stored in a global central space.
Is it a good idea to store all the data in one place ?Yes
Aditya Kharadkar
80
Since the Redux store contains a lot of data, we do not want it to
become very big, so we make use ofSlicesofferedby Redux.
To keep data separate, we create logical partitions in our store. These
partitions are known asSlices.
If we want to keep the data related to the cart, then we will create a
separate slice for the cart. If we want to keep the data related to the
logged in user, then we will create a separate slice for that as well.
Redux says that we cannot directly modify the data in the slice. Redux
offers a way to do that.
Assume that we have a cartSlice which keeps track of the data in the
cart. We have an Addto cartbutton which adds theitem into the cart.
By clicking on this button, we cannot directly modify our cartSlice.
To modify the cartSlice, when the user clicks on the Add To Cart
button, we have todispatch an action.
User clicks the button —> Dispatch an action —> Action calls a
function —> Function modifies the cart slice
Aditya Kharadkar
81
So when the user clicks the button, it dispatches an action. This action
calls the reducer function and this reducer function updates the slice.
We can read the data from the store by something known asSelectors.
When we use a selector to read the data, this phenomenon is known as
Subscribing to the store.
So we can say that the navigation bar is subscribed to our store. That
means the navigation bar will alway be in sync with the store. If the
data in the store (cart slice in this case) changes, then the data shown
on the navigation bar will also change.
Aditya Kharadkar
82
Install Redux
Aditya Kharadkar
83
Create a slice
Aditya Kharadkar
84
● The reducer key is assigned with an object which will have all the
slices (cartSlice in this case).
● The reducer contains the slices where each of the slices contains
its own reducer functions.
● We can subscribe to the store using a selector to read the data
of the store.
● Redux offers a hook nameduseSelectorwhich can beused to
subscribe to the store.
Aditya Kharadkar
85
● This useSelector gives us access to the store where we can find
the cart.items.
● The items of the cart will be stored incartItemswhich we can
use in our component.
● Note - Make sure to access a particular state variable. In our
case, we have accessed cart.items which gives us the exact value
of items.
● If we subscribe only tostore.cart, sometimes thisstore.cart may
contain state variables other thanitems.
● If there is a change in any of those state variables, then it will
re-render thecart componentas well.
● So subscribing only tostore.cart.itemswill makethe Cart
component re-render only when there is a change in theitems.
Aditya Kharadkar
86
Dispatch an action
Aditya Kharadkar
87
● {
Payload: “apple”,
}
● ThehandleAddItemwill be responsible for dispatchingthe action
and it is assigned to the click event of the button. So whenever
the user clicks the button, theaddItemaction willbe dispatched
and it will add that item to the cart.
1.onClick={handleAddItem}
a. This syntax assigns thehandleAddItemfunction directlyto
theonClickevent.
b. When the button is clicked, the handleAddItem function will
be called without any arguments.
2.onClick={() => handleAddItem(item)}
a. This syntax uses an arrow function to call handleAddItem
with theitemargument.
b. This is useful when you need to pass specific arguments to
the handleAddItem function when the button is clicked.
c. Here, theitemneeds to be defined or in scope whenthe
button is rendered.
d. Ifitemis a variable available in the component’scontext, it
will be passed to handleAddItem when the button is clicked.
3.onClick={handleAddItem(item)}
a. This syntax is incorrect and will not work as expected.
Aditya Kharadkar
88
In older redux (vanilla redux), it was not allowed to mutate the state.
We used to create a copy of our state and then modify that. We also
had to return the new state.
This whole process is still done by Redux behind the scenes but now it
is not asking developers to do it. Redux is using theimmerlibrary to do
it.
In the new redux, we have to mutate the state. And it is not mandatory
to return the state as well.
Aditya Kharadkar
89
Types of Testing
1.Unit Testing
a. Unit Testing is a fundamental aspect of software testing
whereindividual components or functions of an application
are tested in isolation.
b. This method ensures that each unit of the application
performs as expected.
c. By focusing on small, manageable parts of the application,
unit testing helps identify and fix bugs early in the
development process, significantly improving code quality
and reliability.
d. Unit tests are typically automated and written by
developers.
2.Integration Testing
a. Integration testing is a software testing process where
software components, modules, or units are testedto
evaluate system compliance concerning functional
requirements.
Aditya Kharadkar
90
Install Jest
We are using jest with Babel, hence we need to install some
dependencies as well.
Aditya Kharadkar
91
***************************************************************
We are using parcel and parcel uses babel. So Parcel has its own
configuration of babel already.
Aditya Kharadkar
92
Configure Jest
1. Would you like to use TypeScript for the configuration file? -> no
(in this case)
2. Choose the test environment that will be used for testing ->
jsdom (browser-like)
a. JSDOM is a library which parses and interacts with
assembled HTML just like a browser.
b. When we run test cases, we do not run them on the browser.
But we need a browser-like environment to run them.
c. JSDOM helps us to get a browser-like environment. It will
give us the features of a browser.
3. Do you want to add coverage reports? -> Yes
4. Which provider should be used to instrument code for coverage?
-> Babel
5. Automatically clear mock calls, instances, contexts and results
before every test? -> Yes
Aditya Kharadkar
93
Install jest-environment-jsdom
Basics of Testing
1. sum.test.js
2. sum.test.ts
3. sum.spec.js
4. sum.spec.ts
Aditya Kharadkar
94
To test this, we first have torender the component onJSDOM. We
will test if <Home /> component is rendered or not.
Aditya Kharadkar
95
Aditya Kharadkar
96
● Then we can run our commandnpm run testto test the
component. When we do that, we will get the below error:
This error says that we can not use JSX inside our test case. JSX
isn’t enabled for our test cases. The error also says that to make
the JSX work, we have to add @babel/preset-react.
Install @babel/preset-react
Now when we run npm run test, we will get another error.
Aditya Kharadkar
97
Install @testing-library/jest-dom
Now when we run the command npm run test, this time our test
cases will be passed.
Aditya Kharadkar
98
Aditya Kharadkar
99
The text of the button in the <Home /> component isClick. So if it
finds this work anywhere in the document, then it will be considered as
a button.
Aditya Kharadkar
100
Aditya Kharadkar
101
● We can group all the test cases in a file using thedescribe()
function.
● This function takes 2 arguments:
○ Description
○ An arrow function
● Inside the arrow function, we can put all the test cases.
● We can also create groups inside a group. To do that, we can put a
describe function inside a describe function.
Aditya Kharadkar
102
Aditya Kharadkar
103
● Consider we have a <Header /> component which is using Redux to
see if the user is logged in or not.
● When we write test cases for such a component, thetest()orit()
function does understand React and JSX, butit does not
understand Redux.
● We know what we aretesting the component in isolation.Hence
it does not have access to theRedux store.
● Sowe have to provide the store to it just like we provide it to our
application.
● So we have toimport Provider from react-reduxand wrap the
<Header /> component inside <Provider store={store}>.
Aditya Kharadkar
104
● Consider that the <Header /> component also uses the <Link> tag
from react-router-dom to allow user to navigate from one page to
another.
● Thetest()orit()function also does not know about <Link>
elementbecause it is not part of React but React router dom.
● So in order to make it work, we have to import the
BrowserRouterfromreact-router-domandwrap our <Header />
component inside it.
● Consider that inside the <Header /> component, we have aLogin
button.
● Upon clicking on this button, the text changes toLogout. That
means before clicking the button, the text isLoginand after
clicking the button, the text isLogout.
● To test this, we have to fire an event inside the test case.
Aditya Kharadkar
105
● In this test case, first we rendered the <Header> component.
● Then we tried to find theLogin buttonusinggetByRole()method.
We gave therole as buttonandwe gave the additional option to
make sure that the name of the button isLogin.
● Then we used thefireEvent()object which has aclick()method
to fire the click event onloginButton.
● The we try to find the button with the name asLogout.
● Then we expect thelogoutButtonto be present in the document.
● This is how we know if the login button is changed to logout
button after clicking the button or not.
Aditya Kharadkar
106
Aditya Kharadkar
107
Integration Testing
● Consider that we have <Body> component which has aSearch box
and Seach button.
● When the <Body> component renders on the browser, it makes an
API call using thefetch()function which is offered bybrowser.
● Let’s test this <Body> component
Note: A test case does not make an actual API call. Because we do
not run it on the browser, so it does not have power to talk to the
world.
Aditya Kharadkar
108
● We are trying to create a mock function of the fetch() function
which is in theglobal object.
● We then make use ofjestwhich has a methodfn()to create a
function. This method takes an argument i.e.an arrow function.
● Inside the arrow function, wereturn a promise which resolves.
This gives us the JSON which also returns a promise.
● So we assigned a function to json which returns a promise which
also resolves to the actual data of the API.
● Note: This data will be themock data we create in the mock
folder. So instead of passing“data”, import the mock data and
pass it here.
Note: Currently, we have to run the npm run test command again
and again after creating test cases. To solve that issue, we can
add a new command in thepackage.jsonfile inside ourscripts.
Aditya Kharadkar
109
Aditya Kharadkar
110
Aditya Kharadkar
111
Aditya Kharadkar
112
● For the change event, browser gives theevent objectwhich has a
target value. But to test this feature, we can give the mock data
i.e.Jeans.
● Then we fire a click event on the search button.
● Then we find the cards using their test id i.e.ItemCard.
● And we expect to have 3 results when we search for Jeans.
Helper functions
1. beforeAll() - This function will be called before running all the
test cases.
2. afterAll() - This function will be called after running all the test
cases.
3. beforeEach() - This function will be called before running every
single test case.
4. afterEach() - This function will be called after running every
single test case.
Aditya Kharadkar
113
useMemo
● Consider that we have a toggle button which handles the dark
mode of the application. The value of the mode is saved in a state
variable. Whenever the button is clicked, this state variable will
change.
● This causes re-rendering of the component every time the button
is clicked.
● Suppose we have a calculation in the same component which is not
related to the dark mode feature. But whenever the button is
clicked, the calculation is performed again.
● If the calculation is a heavy operation, then it will cause the
performance issues.
Aditya Kharadkar
114
useCallback
useRef
Aditya Kharadkar