React Documentation
React Documentation
2. For a default export the import can have any name. For named expost both import
and export should have the same name.
JSX Rules:
1. Every component should return a single ROOT element. To return multiple elements
from a component we can make use of FRAGMENTS.
Fragments lets us group things without leaving a trace in the Browser HTML
tree.
function Avatar() {
return (
<img
className="avatar"
src="https://i.imgur.com/1bX5QH6.jpg"
alt="Lin Lanying"
/>
);
}
4. In the parent component which has a child component we can pass the props as
attribute to the child component.
export default function Parent(){
return (
<Child data={} function=() />
)
5. Props serve the same role as argument serve in a fnnction. Props are the ONLY
arguments to a React componnet.
6. We can set default values to props as we do for arguments. The default values
will only be used when the props value is not present or undefined.
7. PROPS in react are immutable. When a component needs to change its props in
response to a user iteraction or new data , the parent component needs to pass the
new props(new object), User intersactions are handled by state in react.
8. children PROPS. When the child component is nested inside the parent component.
Then the parent componnet will receive the content in a prop called JSX.
example:
import "./styles.css";
import Parent from "./Parent";
import Child from "./Child";
Parent.js
export default function Parent({ children }) {
return <div>{children}</div>;
}
Child.js
export default function Child({ name, age }) {
return <div>{`Child name is ${name} and age is ${age}`}</div>;
}
10. In JSX {condition && <Component />} means if condition is true Componnet will
be displayed else nothing will be rendered.
====================================================================RENDERING
LISTS=============================================================
1. When rendering a list each list item should have a unique key.
2. JSX elements directly inside a map call always needs keys
))
return (
<ul>{listItems}</ul>
)
4. Keys in React: keys helps us to uniquely itentify an item in the list even when
the list is recordered or some of the list items are deleted.
If we DONT spectify key for the list of items in React , React itself will assign
the index of the array as the key. If the array get modified this will cause an
issue.
Similary we shouldn't use Math.random() to create a ke as it will chnage.
Components DO NOT receive keys as props.
==========================================================Keeping Components
Pure======================================================
Pure functions are function which return the same output for a given set of same
input.
React components are called pure components when for the same input they return the
same piece of JSX.
In React there are 3 types of input that we can read while rendering : props,state
and context. When we want to make a chnage depending on user intercation we should
use state instead of changing a local variable.
Side Effects in React : Side Effects are chnages that are happening on the side and
not during the RENDERING of the component.
In React, side effects usually belong inside
event handlers.
**PURE COMPONENTS also help in PERFORMANCE OPTIMIZATION. They help to imporove the
performance by skipping rendering of componnets whose inputs have not chnaged. As
they always return the same result they are safe to cache.
x
==================Understanding Your UI
Tree=============================================
-Module Dependency Tree : It is a tree in which each node represents a module and
each branch represents a an import statement.
-------------------------------ADDING INTERACTIVITY-------------------
=====Responsing To Events=========
When using an event handler in our JSX we need to pass the function to the handler
and not call the function there itseld.
//Passing Event Handler as Props - We can pass event handlers as props from Parent
to child components.
In the child component <button onClick={onClic} > {children} </button>
//Event Propagation ::
State in react is an object that stores information about the component that can
chnage over the lifecycle of the componnet.
HOOKS are special functions which are available only when react is rendering. They
help us to manage state, side effects, context in functional componnets.
STATE is ISOLATED AND PRIVATE : If we render the same component twice , each copy
of the componnet will have completely isolated states independent of each other.
If we want the compononents to use the same state , we need to remove the state
from the child and add it to the cloest shared parent.
Unlike Props, STATE is fully private to the component declaring it. The Parent
componnet cant chnage it.
function handleFirstNameChange(e) {
setName((prevState)=> {
return {
...prevState,
firstName: e.target.value
}
})
}
function handleLastNameChange(e) {
setName((prevState)=> {
return {
...prevState,
lastName: e.target.value
}
})
}
function handleReset() {
setName({
firstName: '',
lastName: ''
});
return (
<form onSubmit={e => e.preventDefault()}>
<input
placeholder="First name"
value={name.firstName}
onChange={handleFirstNameChange}
/>
<input
placeholder="Last name"
value={name.lastName}
onChange={handleLastNameChange}
/>
<h1>Hi, {name.firstName} {name.lastName}</h1>
<button onClick={handleReset}>Reset</button>
</form>
);
}
====
DIFFERENCES BETWEEN CLASS BASED COMPONENTS AND FUNCTIONAL COMPONENTS
======STATE AS A SNAPSHOT============
2. RENDERING means React is calling your component which is a function. When we say
a component re -renders it means that React has called the function again and it
returned a new piece of JSX.
return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);
}}>+3</button>
</>
)
} //Here clciking the button everytime will set the state for the next render ONLY
, so everytime the value will increase by 1.
//If we use prevState then it will increase by 3.
4. *** React DOES NOT update the state during rendering. Even if we update the
state during render it will still hold the snapshot of the state and not chnage it.
***A state variable’s value never changes within a render, even if its event
handler’s code is asynchronous.
return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);
}}>+3</button>
</>
)
} //Here react will batch all the three state updates and re-render will happen
after all these state updates. If we are using setNumber(n=>n+1) then after every
batch update the count will increase by 3.
2. React can batch state updates even from multiple components.
3. eg:
import { useState } from 'react';
return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(number + 5);
setNumber(n => n + 1);
setNumber(42);
}}>Increase the number</button>
</>
)
}
//Output would be 42
function handleLastNameChange(e) {
setPerson((prevState)=> {
return {
...prevState,
lastName: e.target.value
}
})
}
3.In this example we areusing three diifferent handleChnage methods for each object
property. Instread we can use a single handler with [e.target.name] property which
will be dynamically populated.
import { useState } from 'react';
function handleFirstNameChange(e) {
person.firstName = e.target.value;
}
function handleLastNameChange(e) {
person.lastName = e.target.value;
}
function handleEmailChange(e) {
person.email = e.target.value;
}
return (
<>
<label>
First name:
<input
value={person.firstName}
onChange={handleFirstNameChange}
/>
</label>
<label>
Last name:
<input
value={person.lastName}
onChange={handleLastNameChange}
/>
</label>
<label>
Email:
<input
value={person.email}
onChange={handleEmailChange}
/>
</label>
<p>
{person.firstName}{' '}
{person.lastName}{' '}
({person.email})
</p>
</>
);
}
4. In order to change the state of a nested object we use spread operator twice.
function handleTitleChange(e) {
setPerson({
...person,
artwork: {
...person.artwork,
title: e.target.value
}
});
}
5. For updating neseed states we can make use of the Immer library. We can write
the code in a way that it appeas to be mutaty=ing the object but under the hood its
not mutating the object.
To use immer in our code for nested objects we first install npm install use-immer.
And then replace useState with useImmer. With Immer we can perform direct mutation
of objects without creating a copy using spreadf operator.
6. Mutating state is not recommended in React beacuse React uses the previous State
and current state comparision to check if re rendering is required. So we need the
previous state. THIS HELPS IN REACT OPTIMIZATION.
3. Even if you copy an array, you can’t mutate existing items inside of it
directly.
const nextList = [...list];
nextList[0].seen = true; // Problem: mutates list[0]
setList(nextList);
4. Just like in objects we can use Immer for arrays for directly mutatin g their
state and under the hood it is creating a new array and not mutating the original
arrayu.
5. We use the syntax [...arra,newItem] to add a new item to the existing array
without mutating it.
==========================================MANAGING
STATE================================================
Lifting Up State: When we want the components to share state we remove the state
from them and move it to the nearest positioned ansector and pass them dwn as
props. This is called Lifting Up State.
CONTROLLED AND UNCONTROLLED COMPONENTS:
For uncontrolled components the parent componnet cannot influence the information
in the child componnets.
When you want to coordinate two components, move their state to their common
parent.
Then pass the information down through props from their common parent.
Finally, pass the event handlers down so that the children can change the parent’s
state.
It’s useful to consider components as “controlled” (driven by props) or
“uncontrolled” (driven by state).
1. When you give a component state, you might think the state lives inside the
component. But the state is actually held inside React. React associates each piece
of state it’s holding with the correct component by where that component sits in
the render tree.
2. When we are rendering two components side by side each of them will have an
isolated state.
3. When a componnet is removed from a DOM tree its stae is also destroyed. React
preserves a component’s state for as long as it’s being rendered at its position in
the UI tree.
In useState we update the state variable using the state setter function in the
event handler.
In the reducer we dispatch actions from the event handler and update the state
logic in the reducer function.
A Reducer function has two arguments a current state and an action. It returns the
updated state.
** React will set the state to what we return from the reducer.
The Reducer function is named after Javascript reduce method available for arrays.
In a reduce method we pass in a reducer function and the current item.
This reducer function is the same that we use using useReducer.
Step 1: Replacing state update with dispatching actions from the event handlers.
Step 2: Writing the state update logic using the reducer function. It accepts state
and action as arguments.
Step 3: Replacing useState with useReducer and calling the reducer function in the
component.
eg:
const [tasks,setTasks] = useState(initialTasks);
const [tasks, dispatch] = useReducer(reducerFunction,initialTasks);
** So the difference between useState and useReducer is that we are moving the
state update logic out of the componnet into a reducer function.
** Similar to updating regular state array and object in setState without mutation
where we use useImmerState we have useImmerReducer
Advantages of useReducer:
1. As reducer is a pure function that does not depend on the component it can be
tested in isolation.
1. Context lets the parent component make some information available to any
componnet in the tree below it without passing it explicitly throught props.
Steps to useContext:
1. Create a context with the default value. eg: const LevelContext =
createContext(1); The default value can be an object,array,etc.
2. To use the context in the component which needs the data we use the useContext
hook. eg: const level = useContext(LevelContext)
3. Provide the context from the component which specifies the data. Wrap this
component with the context provider.
<levelContext.Provider value={level}>
So when using context, whereever in the component tree we want to specfify the data
we use Context.Provider in that component. And whereever we want to consume it we
use useContext.
All the different React Contexts created in React do not override each other. They
are independent of each other.
`
Use Cases of Context:
1. Theming: If your app lets the user change its appearance (e.g. dark mode), you
can put a context provider at the top of your app, and use that context in
components that need to adjust their visual look.
2. Current Account: Many components might need to know the currently logged in
user. Putting it in context makes it convenient to read it anywhere in the tree.
** Refs are used to directly access or interact with DOM elements and React
components in a way that's outside of React data flow.
1. When we want the component to remember some information , but you dont want the
information to trigger new renders , we can use refs.
2. const ref = useRef(10);
useRef() returns an object like this {current:0}. To access the current property of
the useRef() hook we use ref.current.
4. Use of Refs:
1. Refs can be used in places wherein we want to store some information which
does not cause re rendering.
In a stopwatch to store the interval information we can use it. This is
because when a component re renders all local vaiables gets
initialized from scratch. That is why we cant store the interval ID in the
local variable.
2. Refs can be used to directly access the DOM nodes so that we can focus a
node, scroll to it, or measure its size and position.
* Debouncing lets us delay some action until the user "stops doing things".
1. We can refernce a DOM node to a ref using useRef. The DOM node to which we want
to refrence, we need to pass a prop ref to it.
3. ref can be passed down the component tree as props. This way the ref created in
the parent componnet can point to a DOM node in the
child component.
4. When we are forwarding the ref from a parent to child. In this the ref declared
in the parent is pointing to the DOM node in child.
So now the parent can call the focus method on it. In a simnilar way the parent
can also change the CSS style of the child component
DOM node.
To avoid this we use useImperativeHandle(). useImperativeHandle provides the
parent component access to only those methods which are defined
inside it.
The useImperativehandle provides an special object as the value of the ref to
the parent. This object contains the methods we want to expose
to the parent componnet.
**Effects lets us run some code after the rendering of the component so that we can
synchronise our
component with some system outside of React.
**Effects are used to step out of your React code and synchronize with some
external systems.
** SIDE EFFECTS:
Event handlers contains side effects i.e they change the state of the component
based on specific user action.
Effects lets us specify side effects that are caused by rendering itself ,
rather than by a particular event.
eg. Sending a message in the chat is an event but setting a server connection is
an Effect.
2. Everytime the component renders, React will update the screen and then run the
code inside useEffect.
3. Effects run after every render. So setting up the state inside useEffect will
cause an INFINITE LOOP. As the effect will run it
will set the state and which in turn will cause re rendering and again the
effect will run.
useEffect(()=> {
setState(data+1)
})
4. If the array of dependencies are not specified in useEffect it will run after
every render.
5. The dependency array can contain multiple dependencies. However React will only
skip running the Effect if all the listed dependencies
have the same value to what they had in the previous render.
6. If the dependency array is empty it will run only once on the component mounts
i.e appears on the screen for the first time.
7. React calls the cleanup function each time before the useEffect runs and one
final time when the component unmounts.
useEffect(()=>{
function handlerScroll(e){
console.log(window.x,windowe.y)
}
window.addEventListener('scroll',handleScoll)
return ()=> window.removeEventListener('scroll',handleScroll)
},[])
10. Some logic should only run once when the component starts. You can put it
outside your component.
12. When you move from one page to another and then again come back to the page the
effect will again run afetr render opf the page.
14.Note that measuring performance in development will not give you the most
accurate results. (For example, when Strict Mode is on,
you will see each component render twice rather than once.)
To get the most accurate timings, build your app for production and test it on a
device like your users have.
16. To fix the race condition, you need to add a cleanup function to ignore stale
responses: race condition is several actions causing side effects running
in parallel.
===========================================================Lifecycle of Reactive
Effects=========================
1. In a ChatRoom componnet if we want to create a connection we synchroonize with
the external system.
This synchronization will not only happen on mounting of component and similiar
stopping of the synchronization will not happen
on only on unmount of the component.
On the same page if we try to asccess a dropdown which connects to different
external system then to synronization will occur.
***useEffect() will be called after every re render only when the list of
dependencies changes.
**The list of dependencies can contain any props,state or variable that are
dependent on props and state in a component that could
change over the lifecycle of the component.
**All values inside the component (including props, state, and variables in your
component’s body) are reactive.
Any reactive value can change on a re-render, so you need to include reactive
values as Effect’s dependencies.
**If we have linter configured in react, then it will check if all the reactive
values used by the Effects code is declared in the list
of dependencies.
**We will use an event handler when there is a change needed on the page based on
an user iteraction. And we will use effect when
we want to do something based on the page re render. for example: creating a
connection on page load.
**Logic inside a event handler is non reactive whereas logic inside an effect is
Reactive.i.e , it will change with every render.
We can pass non reactive logic out of useEffect into useEffectEvent.
**When we write an effect linter verfies that we have included all the reactive
values in the effect dependecies list.
**The dependency list is a list of all the reactive values used by the Effects
code.
**In JavaScript, each newly created object and function is considered distinct from
all the others.
It doesn’t matter that the contents inside of them may be the same. So everytime
the useEffect is called after a re render the
object will be a new one. So we should try to avoid objects and function in the
array of dependencies.
* We cannot use hooks inside a regular function.Only hooks can call other hooks.
* use prefix should be used for functions which call other hooks and not for any
other function.
2. Custom Hooks let you share stateful logic but not state itself. Each call to the
hook is completely independent of every other call
to the same hook.
State Hooks:
1.useState
2.useReducer
Context HOOKS
1.useContext
Ref HOOKS
1.useRef
2.useImperativeHanlde
Effect Hooks:
1.useEffect
2.useLayoutEffect
3.useInsertionEffect
Performance Hooks:
A common way to optimize the performance of the react application is to avoid
unnecessary re rendering.
We can tell react to use a cached calculation or to skip a re render if the data
has not changed since the previous render.
1.useMemo
2.useCallback
3.useTransition
4.useDefferedValue
====useMemo=========
useMemo is a react hook which lets us cache the result of the complex calculation
between re renders.
Uses of useMemo:
1. When filtering or tranforming a large array.
2. In complex calculations (If we are looping over thousands on objects)
3. To skip the re rendering of the child component if the props hasn't changed.
Example of useMemo
**In React when a component re-renders , react re renders all its child
recursively.
To skip the re renering of the child component we can wrap it inside memo. This
way the child will skip re rendering if all its
props are the same as the last re render.
** In case of functions and objects they will change after each re-rendering. So if
the object or function is being used in the
calculation process we should either memoize them or include the useMemo wherein
we are doinbg the calculation.
=======useCallback==================
useCallback is a React hooks which lets us cache the function definition between re
renders.
React will return the function(and not call it) during the initial render. If the
dependencies remain the same during next renders
react will return the same function.
**In order to avoid the re rendering of the child component we wrap it inside a
memo.
** When we are passing a function for example handleSubmit from Parent to Child. If
we are not wrapping it inside useCallBack
it the function will change after every re render and hence the child componnet
will also re render. To avoid this we need to
wrap the function inside useCallback and the child component inside useMemo.
==============useDefferedValue============
It is a React hooks which lets you defer updating a part of the UI.
======useTranstion===================
useTransition is a React hook which lets us render a part of the UI in the
background.
Syntax:
const [isPending, startTransition] = useTransition()
--useTransition returns an array with two items. First the isTransition flag that
tells us whether there is a pending transition.
The startTransition function that
lets you mark updates as a Transition.
--Usage:
If we have a component with two useState(). One for updating a value and the second
for updating the state. Now if the
second useState() updater function has to loop over a list in order to update a
list it will take up a lot of time.
And since react batches the state updates the update of the first useState(0 will
also be delayed.
To resolve this we have useTransition. We pas the updater function which is taking
up a lot of time as a callback inside startTransition()
and this state update should happen in the background and it not delay the other
state updates.
========================useLayoutEffect===================
Usage:
1.synchronizing state with the DOM
2.DOM measurements and manipulations
==============useInsertionEffect================\
=============================Profiler==============================================
==================================
<Profiler> lets us measure the rendering performance of a React tree
programmatically.
--The onRender method has an actual Duration and a base duration. The actual
duration returns the time take for the component to
re render with all its optimizations. The base duration returns time taken
without optimization.
--StrictMode will re render an extra time to find bugs caused by impure components
i.e you are trying to mutate the oriinal state.
==============Suspense===============
Suspense lets us display a fallback UI until its children have finished loading.
We need to wrap the components inside the Suspense Boundary.
Sytax:
<Suspense fallback={<Loading/>}>
////
</Suspense>
--What Sunspense does is it suspends the children component till is has completed
its action and in the meanwhile display a fallback UI.
Usage:
Suspense can be used to display nested contents as it loads.
<Suspense fallback={<BigSpinner />}>
<Biography />
<Suspense fallback={<AlbumsGlimmer />}>
<Panel>
<Albums />
</Panel>
</Suspense>
</Suspense>
=========================================================================
lazy:
lazy lets us defer loading the component code until it is rendered for the first
time.
**Inside lazy we are passing in a load function which returns a promise or another
thenable(A promise like object wirth an then method).
Once the component is rendered for the first time react will call load. Both the
returned Promise and Promise resolve value will be cached.
** Using lazy we defer loading the components code until it is rendered for the
first time.
**Dynamic imports require that the lazy component we are exporting require to be a
default export.
** Till the component is rendered we can use Suspense to wrap the lazily loaded
component to display a fallback UI.
If the promise rejects the nearest Error Boundary will handle it.
Example:
We have a textbox and an checkbox button. We want to show the typed in details of
the textbox on the same page on cluick of the checkbox. For this
we can use lazily load the component which contains the code.
If we perform the same for the next time it will not load again as react caches the
result.
===================================Additional Topics=================
Q. Difference between Library and Framework?
In a library we get to decide how to structure our application. For example in the
MVC architecture , react acts as a view layer.
The model(state) can be controlled by redux and control by routing.
app.use(cors({
origin: 'https://your-react-app.com', // Your React app's URL
}));
In both async and defer the script is fetched asynchronously. However in defer the
file is executed only once the HTML is fully parsed.
Q.NPM -> It is a tool used for package management. npm init creates the
package.json file.
QWebpack and Parcel and VIte - These are web application bundlers.
Features:
1. Hot Module Replacement - It tracks the file changes via file watcher algorithm
and render the changes in the file.
2. dev and production build - super fast building algorithm
3. Image Optimization
4. caching during devlopement - This reduces the building time
5. Automatic code splitting
6. Minification
Q Dev dependencies -> Bundler are a part of dev dependencies. They are not required
in prod. npm i --save-dev
Q. Tree Shaking - It is the process of removing unwanted code that we do not use
while developing the application.
Tree shaking is a process used in JS bundlers to remove unused code from the
final bundle during the build process.
It checks for imports and exports which are not being used in the final bundle
and removes them.
--Redux
--Webpack
--React Testing(Jest and Enzym)
--Axios/fetch/interceptors
-Error Boundary
--React MFEs (single SPA applications)
https://lmsportal.atlassian.net/browse/TS-16738
https://lmsportal.atlassian.net/browse/TS-16784
https://lmsportal.atlassian.net/browse/TS-16770
https://lmsportal.atlassian.net/browse/TS-14458