React Interview Qution and Answers
React Interview Qution and Answers
EXECUTION CONTEXT:
execution context in JavaScript as a kind of box where everything
happens. Inside this box, you have two main parts.
First, there's the memory component, which is like a storage area for all
your variables and functions. This part is also called the variable
environment. It's where JavaScript keeps track of all the key-value pairs
for your program.
Then, you have the code component. This is where your actual code gets
executed, line by line. It's like a thread of execution that goes through
your code step by step.
JavaScript is considered a synchronous single-thread language, which
means it processes one task at a time in a sequential order .
Stack: Function calls and local variables.
Heap: Objects and dynamic memory allocation.
hoisting:
Hoisting is like JavaScript's way of moving variable and function declarations to
the top of their scope before running the code. With var, you can use the
variable before declaring it, but it'll be undefined. with let and const, you can't
use them before declaring them, or you'll get an error.
Function declarations: Fully hoisted.
var - Hoisted
Arrow functions: Not hoisted
Anonymous Function expressions: Not hoisted
let and const - Hoisted but not initialized. (Temporal dead zone).
class declarations - Hoisted but not initialized.
temporal dead zone:
It is a specific time period in the execution of java script code where the
variables declared with let and const exists but cannot be accessed until
the value is assigned.
Any attempt to access them result in reference errors
function somemethod() {
console.log(counter1); // undefined
console.log(counter2); // ReferenceError
var counter1 = 1;
let counter2 = 2;
}
Es6:
Arrow functions
Let and Const declarations.
Destructuring assignment
Default parameters
Template literals
Spread and Rest operators
Promises
Classes
Modules
Map, Set, Weakmap, Weakset
Let const var:
Variables declared with var are function scoped.( available through out the
function where its declared ) or global scoped( if defined outside the function ).
Variables declared with let and const are block scoped.
var and let can be reassigned. const cannot be reassigned
var gets hoisted and initialized with undefined. let and const - gets hoisted to
the top of the scope but does not get assigned any value.(temporary dead zone)
if(true){
var a = 'hello'
}
console.log(a) //hello output
if(true){
let a = 'hello'
}
console.log(a) //let varible is not define,
arrow function:
Arrow functions are introduced in ES6. They are simple and shorter way to write
functions in javascript.
it cannot be accessed before initialization
this function does not have access to arguments object
and also these function does not have their own this. Instead, they inherit this
from the surrounding code at the time the function is defined.
Arrow functions cannot be used as constructors. Using them with the 𝙣𝙚𝙬
keyword to create instances throws a TypeError.
Arrow functions cannot be used as generator functions.
generator function:
A generator function is a function which can be paused and resumed
at any point during execution.
They are defined by using function* and it contains one or more yield
expressions.
The main method of generator is next(). when called, it runs the
execution until the nearest yield.
It returns an object which contains 2 properties. i.e., done and value.
done: the yielded value value: true if function code has finished. else
false.
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
return 4;
}
Spreadoperator:
Spread operator is used to spread or expand the elements of an iterable like
array or string into individual elements.
Concatenating arrays.
let x = [1,2];
let y = [3,4];
restoperator:
Rest operator is used to condense multiple elements into single array or object.
This is useful when we dont know how many parameters a function may receive
and you want to capture all of them as an array..
function sum(...numbers) {
return numbers.reduce((acc, val) => acc + val, 0);
}
destructuring:
It is used to extract values from arrays or objects and assign them to variables
in a concise way. It's a handy feature for quickly accessing specific elements or
properties without writing lengthy code.
const user = {
"age": 10,
"name": "praveen"
}
const {age,name} = user;
console.log(age,name) // 10,"praveen"
//example 2
const [a,b] = [1,2];
console.log(a,b) // 1,2
map vs set:
Map is the collection of key value pairs
Map is two dimensional
new Map([iterable]) – creates the map, with optional iterable (e.g. array) of
[key,value] pairs for initialization.
map.set(key, value) – stores the value by the key, returns the map itself
map.get(key) – returns the value by the key, undefined if key doesn’t exist in
map
map.has(key) – returns true if the key exists, false otherwise.
map.delete(key) – removes the element by the key, returns true if key existed
at the moment of the call, otherwise false.
map.clear() – removes everything from the map.
map.size – returns the current element count.
modules:
Modules allows us to break down the large piece of code into smaller parts.
Modules helps us to write more reusable and maintenable code.
Modules can be imported and exported using import and export statements.
objects:
let animal = {
name: "Animal name"
}
object constructor:
object.seal : it is used to modify existing property and can’t add new property
also can’t delete.
let data = {
a : 10
};
Object.seal(data);
data.a = 20;
data.c = 30;
console.log(data)
Output:
data: {
a: 20
}
Array methods:
push: Add one or more elements to the end of an array.
let a = [1, 2, 3];
a.push(4, 5);
console.log(a); // Output: [1, 2, 3, 4, 5]
Slice:
If we want to create an array that is subset of existing array with out
changing the original array, then we will use slice.
let arr = [1,2,3,4];
let newArr = arr.slice(1,3);
console.log(newArr) // [2,3]
Eval:
eval function evaluates javascript code represented as a string. The string can
be javascript expression, variable, statement or a sequence of statements.
console.log(eval("1 + 2")); // 3
undefine:
These variables are declared in the program but are not assigned any
value.
If we try to access the value of undefined variables, It will return
undefined.
Undeclared:
when we try to access any variable that is not initialized or declared
earlier using var or const keyword.
These variables does not exist in the program and they are not declared.
If we try to read the value of undeclared variable then we will get a
runtime error.
Null:
null is nothing but represents the intentional absence of any value.
Datatypes: not a number
Number, string, Boolean , big int, null, undefine, symbol,
== vs ===:
== is used for comparing two variables, but it ignores the datatype of
variable.
=== is used for comparing two variables, but this operator also checks
datatype and compares two values. Basically === is strict comparison.
let x = 100; number
let y = "100" string
if (x === y) {
alert("x and y are equal")
} else {
alert ('x and y are not equal')
}
eventloop:
the event loop manages asynchronous operations. When you use
functions like setTimeout, the callback isn't executed right away. Instead,
it's added to a queue. The event loop checks if the call stack is empty and,
if it is, moves the callback from the queue to the call stack. This process
manages that asynchronous operations don't block the main code
execution, making JavaScript efficient for handling time-consuming tasks.,
events:
Events are the action creators ,it simply represents user interactions or
changes on we page
We have several types of events mouseevents,keybordevents,
formevents, windowevents,eventdeligation,
with in the mouse events we have we have
onClick,onmouseHover,onmouseout,onmousedown,
keyup,keydown,and form events submit,input,change.
Event Bubbling:
Event bubbling is a type of event propagation where the event
first triggers on the innermost target element, and then
successively triggers on outer most DOM element
When you click the button, the event will first trigger on the button itself.
Then, it will bubble up through each containing div,
<!DOCTYPE html>
<html>
<head>
<title>Event Bubbling</title>
</head>
<body>
<div id="div1" style="padding: 50px; border: 1px solid black;">
Div 1
<div id="div2" style="padding: 50px; border: 1px solid red;">
Div 2
<button id="button1">Click Me</button>
</div>
</div>
<script>
document.getElementById('div1').addEventListener('click', function() {
console.log('Div 1 clicked');
});
document.getElementById('div2').addEventListener('click', function() {
console.log('Div 2 clicked');
});
document.getElementById('button1').addEventListener('click', function(event) {
console.log('Button clicked');
// To stop the event from bubbling up
event.stopPropagation();
});
</script>
</body>
</html>
capturing:
<!DOCTYPE html>
<html>
<head>
<title>Event Capturing</title>
</head>
<body>
<div id="div1" style="padding: 50px; border: 1px solid black;">
Div 1
<div id="div2" style="padding: 50px; border: 1px solid red;">
Div 2
<button id="button1">Click Me</button>
</div>
</div>
<script>
document.getElementById('div1').addEventListener('click', function() {
console.log('Div 1 clicked');
}, true);
document.getElementById('div2').addEventListener('click', function() {
console.log('Div 2 clicked');
}, true);
document.getElementById('button1').addEventListener('click', function(event) {
console.log('Button clicked');
// To stop the event from propagating further
// event.stopPropagation();
}, true);
</script>
</body>
</html>
propagation:
polyfill:
while we are working new js features older browser cannot understand , at that
time using polyfill we can check if the feature is supported or not ,and also
provide additional implementation .
// Custom implementation of Array.prototype.forEach
Array.prototype.forEach = function(callback) {
for (let i = 0; i < this.length; i++) {
callback(this[i], i);
}
};
// Example usage
let data = ["sai", "krishna"];
Hof:
A function which takes another function as an argument or returns a function as
an output.
Map vs filter:
Both map and filter are useful in JavaScript when working with an arrays.
map transforms each element of an array and creates a new array which
contains the transformed elements. whereas filter will creates a new array with
only those elements which satisfies the specified condition.
Map vs foreach:
map method is used to transform the elements of an array. Whereas
forEach method is used to loop through the elements of an array.
map method will return a new array with the transformed values. forEach
method does not return a new array.
map method can be used with other array methods like filter method.
whereas forEach method cannot be used with other array methods as it
does not return any array.
reduce: reduce method reduces an array to a single value by applying a callback
function to each element, with an optional initial value
Reduce method reduce an array of values down to just one value.
Just like map and filter reduce also executes the call back from each
element of the array it receives two things one is call back function and
initial value.
find:
It will return the first element of array that passes specified condition.
function findMethod(){
let arr = [{id:1,name:"sai"},{id:2,name:"krishna"}];
let data = arr.find(x=> x.id==2)
console.log(data)
}
findMethod()
Output:
{id:2,name:"krishna"}
findIndex:
It will return the index of first element of an array that passes the
specified condition.
function findMethod() {
let arr = [
{ id: 1, name: "sai" },
{ id: 2, name: "krishna" },
];
let data = arr.findIndex((x) => x.id == 2);
console.log(data);
}
findMethod();
Output: 2;
Forinforof:
Both for-in and for-of are used to iterate over the datastructure.
for-in:
for-in iterates over the enumerable property keys of an object.
for-of:
for-of is used to iterate over the values of an iterable object.
Examples of iterable objects are array,string,nodelists etc. (for of on
object returns error).
purefunction:
Pure functions are the functions which will return same output
for same arguments passed to the function.
This will not have any side effects.
It does not modify any non local state.
function greeting(name) {
return 'Hello $ {name}';
}
console.log(greeting("praveen"));
Impurefunctions:
Impure functions are the functions which will return inconsistent
output for same arguments passed to the function.
This will have side effects.
This will modify non local state
FirstClass function:
A function can be treated like a variable their functions are called first-
class functions.
In these cases functions can be passed another functions can be used
manipulated and return from those functions ,and basically every thing a
variable can do a function can also do.
So these is why a function as a first-class function .
iife:
IIFE is a JavaScript function that runs as soon as it is defined
functions which are executed immediately once they are mounted to the stack
is called iife. They does not require any explicit call to invoke the function.
invoked a function
function square(num){
console.log(num * num)
}
square(5)
is Iife function
(function square(num){
console.log(num * num)
})(5)
thiskey:
This key word is used reference something .
It mean will refers to the current execution context, its value is
simply determine how the function is called.
Basically this key word used out side of any function or object it
refers to the global object.
Eg: window in browser object
If we used with in the function it refers global object by default.
While using this in event handler its refers to the dom element.
nonstrict:
Its a global object.
In non strict mode, when ever this keyword value is null or undefined,
js will replace it’s value with global object.(Due to this substitution
Keys:
Keys are used to uniquely identify the elements in the list. react will
use this to indentify, which elements in the list have been added,
removed or updated.
function MyComponent() {
const items = [
{ id: 1, name: "apple" },
{ id: 2, name: "banana" },
{ id: 3, name: "orange" },
];
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
callback:
A callback is a function which is passed as an argument to another
function which can be executed later in the code
callbackhell: when multiple asynchronous operations are nested
within each other, leading to deeply nested and hard-to-read code.
This structure can make code difficult to maintain and manage.
Promises:
Promises are used to handle asynchronous operations. They have four
states: pending, fulfilled, and rejected and settled, Once a promise is
fulfilled,
Fulfilled: The promise has completed successfully, and its handler will
be executed.
Rejected: The promise has failed, and its error handler will be
executed.
Pending: The promise is still in progress, neither fulfilled nor rejected.
Settled: The promise is either fulfilled or rejected; it is no longer
pending.
let promise = new Promise(function(resolve,reject){
const x = "Saikrishna";
const y = "Saikrishna";
if(x === y){
resolve("Valid")
} else{
let err = new Error("Invalid")
reject(err)
}
})
promise.then((response)=>{
console.log("success",response)
}).catch((err)=>{
console.log("failed",err)
})
Promise chaining:
Promises chaining is a technique used in JavaScript to handle
Asynchronous operations in a more readable and manageable
way.
It provides clean a organized way to handling Asynchronous
code sequence wise multiple Asynchronous operation one after
one.
.all:
It Will wait for all of the promises to resolve or any one of the promise reject.
.allsetteled:
Will wait for all the promises to settle (either fulfilled or rejec ted)
.Race: Will return as soon as when any one of the promise is settled.
.any:
Will return if any one of the promise fulfills or rejects when all the promises are
rejected
asyncawait:
"Async/await simplifies asynchronous programming by allowing
functions to pause and wait for promises to resolve, making code
easier to read and write compared to traditional promise chaining."
Async/await is a modern JavaScript feature used to handle promises
in a more readable and synchronous-like manner. The async keyword
is used before a function declaration to mark it as asynchronous,
meaning it will always return a promise. The await keyword is used
inside async functions to pause execution and wait for a promise to
resolve, allowing other code to run in the meantime. Async/await
simplifies asynchronous code by avoiding nested promise chains,
making it easier to write and understand asynchronous code.
let name1 = {
firstName: "praveen",
lastName: "Nangunuri"
}
let name2 = {
firstName: "Learn",
lastName: "depth"
}
printName.call(name1,"Call Hello");
printName.call(name2,"Call Hello");
printName.apply(name2,["Apply Hello'])
The only difference between call and apply is that syntax of how we
pass the arguments.
bind: This gives us a copy which can be invoked or executed later
rather than directly invoking it whereever we are writing this line of
code.
We can use bind() for events like onClick where you dont know when
they will be fired but you know the desired context.
let name1 = {
firstName: "praveen",
lastName: "Nangunuri"
}
let name2 = {
firstName: "Learn",
lastName: "depth"
}
debounce& throttaling
These techniques help optimizing performance by controlling the
frequency of function execution
Debouncing is nothing but if try to call any function after certain
amount of time the the function is invoked.
let suppose we have one search functionality when we type any thing
each letter should trigger api this the performance issue if you
overcome this we can use debounce technic .
// debounce;
const debounce = (fun, dely) => {
let timeOutId;
return (...args) => {
clearTimeout(timeOutId);
timeOutId = setTimeout(() => fun.apply(this, args), dely);
};
};
const myFunction = () => {
console.log("praveen");
};
const debounceFunction = debounce(myFunction, 2000);
debounceFunction();
debounceFunction();
debounceFunction();
sessionstorage :
it is nothing but data stored in particular session time only , when the
browser closed the data collapsed.
Limited storage, around 5mb of data. Simple key-value storage.
localstorage: but coming to local storage even browser is closed again
open the browser the data still present the storage.
Both provides same methods,
Just integrate
IndexedDb:
It is used for storing large amount of structured data.
It uses object oriented storage model.
Persist data beyond the duration of page session
Cookies:
Cookies are used to store information about the user in the
webpages. Cookies are stored as key value pairs and hold 4kb of data.
When user logins to the application, server uses the set-cookie http
header in the response to set a cookie with a unique session
identifier. Next time when user makes the api requests, cookie will be
sent in the http header by using which server will identify who the
user is.
Interceptors:
Interceptors allows us to modify the request or response before its
sent to the server or received from the server.
import axios from 'axios';
// Request interceptor
axios.interceptors.request.use((config) => {
if (longUrls.includes(config.url)) {
config.timeout = 1000; // Set timeout to 1000ms (1 second) for specified
URLs
}
return config;
}, (error) => {
return Promise.reject(error);
});
// Response interceptor
axios.interceptors.response.use((response) => {
return response;
}, (error) => {
return Promise.reject(error);
});
Shallow copy
Shallow copy it is used to copy of the object , if the copy object
changes existing object also changes.
Using object.assign(),
let originalArray = [1, 2, [3, 4]];
let shallowCopy = [...originalArray];
shallowCopy[2][0] = 100;
console.log(originalArray); // Output: [1, 2, [100, 4]]
deep copy.
Deep copy creates new copy of the original object ,if copy object
changes does not effect on the original object.
Using Json methods like json.parse and json.stringify.
let originalArray = [1, 2, [3, 4]];
passbyvalue:
In JavaScript, whenever a function is called, the arguments can be
passed in two ways, either pass by value or pass by reference.
Pass by value, parameters passed as an arguments creates their own
copy. So any changes made inside the function are made to the copied
value so it will not affect the original value.
Primitive datatypes such as string, number,boolean,null and
undefined are passed by value.
function changeNum(value) {
value = 20;
console.log(value); // Output: 20
}
changeNum(num);
console.log(num); // Output: 10
Passbyrefrence:
Pass by reference, parameters passed as an arguments does not
creates their own copy. so any changes made inside the function will
affect the original value.
Non -primitive datatypes such as object,arrays or functions are passed
by reference
addToArr(arr);
console.log(arr); // Output: [1, 2, 3, 4]
Inheritance:
one object to access the methods and properties of another object.
prototype:
If we want to add properties at later stage to a function which can be accessible
across all the instances. Then we will be using prototype.
prototype is known as it is type of inheritance it access the methods and
properties of the other object
function Student() {
this.name = "Saikrishna";
this.exp = "8";
}
Student.prototype.company = "Hexagon";
console.log(std1);
console.log("Company of std1:", std1.company); // Output: Hexagon
console.log(std2);
console.log("Company of std2:", std2.company); // Output: Hexagon
// output
Student { name: 'Saikrishna', exp: '9' }
Company of std1: Hexagon
Student { name: 'Saikrishna', exp: '10' }
Company of std2: Hexagon
Babble:
Babble is JavaScript compiler and we also called as trans piler .
It is basically takes your jsx and its converts it react create element.
https:
400 -> bad request ,some thing wrong what the user sent to the server,
To fix check what the user sent and make sure in right foramte,
200 -> success,
404 -> not found -> server could not find the what the user asked
500 => internal server
Some thing went wrong on server.
some:
will check if atleast one of the element in the array satisfies the
specified condition. It returns true if any element passes the condition.
else returns false.
every:
will check if all the elements of the array satisfies the specified
condition. it return true if all the elements satisfies the condition, else
returns false.
React:
1. React is a JavaScript library for building fast and interactive user
interfaces for the web as well as mobile apps.
2. It is open source any user can access its source code modify and
enhance it .
3. It helps in create dynamic web applications and also provide
performance enhancement.
4. Basically there are several performance enhancement like virtual
dom and one way Databinding.
5. And also react uses reusable components this helps decrease
development time.
6. React involves unidirectional data flow of data .
Features:
Jsx:
JSX is HTML-like or XML-like syntax.
JSX stands for JavaScript XML. It's a syntax extension for JavaScript.
It is not a part of React. React apps can be built even without JSX but the
code will become very hard to read.
JavaScript engine cannot understand JSX as it only understands
ECMAScript
Virtual Dom:
virtual dom is a light-weight representation of the real dom, let suppose a
component is initially rendered here react creates virtual dom representation of
the component ,with the component when the state or props changes new
virtual dom is created ,here new virtual dom compare to the previous virtual
dom simply find what has changed , only that changes is updated on ui ,this
process is diffing .
reconciliation:
reconciliation is nothing but how the updates the dom with in
the react.
When ever the states or props of component to change ,react needs to
take a decision whether its needs to update the dom .
onewaydatabinding:
Onewaydatabinding is nothing but the data is flowing from parent to child
component.
Twowaydata binding:
two way databinding is nothing but the data flowing from parent to child
component , the child component sending the data to parent component.
shadowdom:
State vs props:
Both props and state are used to manage the data of a component.
State is used to hold the data of a component whereas props are used to send
data from one component to another component.
State is mutable but props are immutable.
Any change in state causes rerender of component and its children.
Propdrilling:
Props drilling is the process of sending the data from one component to the
component thats needs the data from several interconnected components
proptype:
proptype is used to type checking purpose ,when you implement any
application if you want find out type checking errors kind of bugs we can
use proptype , it is not crashed the application it showing warning in
console during development.
defaultprops:
default props mean you pass some default values,
you know some times all props are not sent by the parent component ,
at that time you set some values in your component with help of default
props.
childtoparent:
In the parent component ,create a call back function .this call back
function will get back the data from the child component .pass the call
back function to the child as a props from the parent component .the
child component call the parent call back function using props and
pass the data to the parent component
functionvsclass:
class based components is older way of writing code ,
it is extend by React.component,
with in this if you want mange the state use ‘this.state’ and also
we have used life cycle methods .
functional components are just like normal functions ,
if you want manage state usestate,
if you want implement lifecycle behavior using useeffcet,
purecomponent:
1. Pure components are used for better performance by preventing
unnecessary re-renders when state or props remain unchanged.
2. When you update the state in the parent component the child component
also re-render ,you want over come this issue use pure components.
3. Switching a class component to React.PureComponent helps achieve this.
4. By inheriting from React.PureComponent, React automatically manages
prop updates and triggers re-renders only when necessary.
5. import React, { PureComponent } from 'react';
6. class MyPureComponent extends PureComponent {
7. render() {
8. return (
9. <div>
10. <h1>Pure Component Example</h1>
11. <p>Props: {this.props.text}</p>
12. </div>
13. );
14. }
15. }
16. export default MyPureComponent;
hoc:
Higher order component is nothing but a function that takes a
component and returns a enhanced component.
Basically, takes a component as input and it enhance it the component .it
add some extra features of the component and returns it back.
It adds like enhancer kind of function it takes existing component. and
just enhance it.it just modifies the component twist it little and return
back.
HOC can be used for many use cases:
Code reuse, logic and bootstrap abstraction.
Render hijacking.
State abstraction and manipulation.
Props manipulation.
renderprops:
share the render logic by using props
it is a technique for sharing code between react components using a prop
whose value is a function.
routing:
routing is nothing but simply enable the navigation between different
components,
Routing in web applications enables navigation between different URLs. There
are two main types:
1. Client-Side Routing:
Handled in the browser using JavaScript frameworks like React
Router.
Pros: Faster transitions and a more interactive experience.
Cons: SEO challenges and potentially slower initial load times.
2. Server-Side Routing:
Handled on the server, generating new HTML pages for each
request.
Pros: Better for SEO and faster initial loads.
Cons: Slower page transitions and less interactivity.
A hybrid approach combines both methods, using techniques like Server-Side
Rendering (SSR) or Static Site Generation (SSG) to optimize performance and
SEO.
client-side routing is suitable for building SPAs and offers faster, more
interactive user experiences but can pose SEO challenges. Server-side
routing is more SEO-friendly and is used for traditional websites with
separate HTML pages, but it can be slower in terms of page transitions.
The choice between these two routing approaches depends on the
specific requirements and goals of a web application or website. In
some cases, a hybrid approach that combines both client-side and
server-side routing techniques may be used to achieve the best of both
worlds.
rendering:
conditional rendering in react is a way to display certain components or
content based on specific conditions or rules
decision making about when to show what content is where conditional
rendering comes into play
strictmode:
React.StrictMode is a useful component for highlighting potential problems in
an application. Just like , does not render any extra DOM elements. It activates
additional checks and warnings for its descendants. These checks apply for
development mode only.
Identifying components with unsafe lifecycles
Warning about legacy string ref API usage
Warning about deprecated findDOMNode usage
Detecting unexpected side effects
Detecting legacy context API
lifecycle methods:
React lifecycle methods are divided into four phases: Mounting, Updating,
Unmounting, and Error Handling.
In this phase the component is generally mounted into the dom. It is an
initialization phase where we can do some operations like getting data
from api, subscribing to events etc.
ComponentDidMount(): This is called once component is mounted into
the dom.
Eg: fetch api calls, subscribing to events etc.
Updating phase:
This is when the component is updated. The component will be updated
when ever there is change in state or props.
ComponentDidUpdate:
Called after the component is updated in the dom.
Unmounting phase:
In this phase the component will be removed from the dom. here we can do
unsubscribe to some events or destroying the existing dialogs etc
ComponentWillUnmount: This is called when component is about to be
removed from the dom.
hooks:
useEffect:
Useffect perform ability to side effects ,
It accepts two arguments: a callback function and an optional dependency
array.
without a dependency array, the callback function runs after every render
of the component.
If an empty dependency array [] the callback function runs only once after
the initial render.
the dependency array contains variables, the callback function runs after
the initial render and then whenever one of the variables in the
dependency array changes.
return ()=>{
console.log("Any cleanup activities/unsubscribing ")
}
})
UseContext:
The useContext hook provides a way to pass data through the component
tree without manually passing props at every level, solving the problem of
prop drilling..
We need to follow 3 main steps to implement context api in our application.
Create context Create Provider and wrap this provider around root level
component and pass the data. Create consumer and utilize data using
useContext.
usereducer:
Usereducer is hook it is used for state management . while you
implementation complex satate logics , if your state depending on the
previous state ,
usecallback :
useCallback is for memoizing functions to avoid unnecessary re-creations.
useMemo is for memoizing values to avoid unnecessary recalculations..
It will give memorized function
When passing functions to child components to avoid them re-rendering
unnecessarily.
Purpose: Keeps the same function instance between renders unless its
dependencies change.
functions remain the same unless their dependencies change
usememo:
it will give memorized value
is used when you want to memorize a value or the result of a computation only
re-run when necessary.
It is used to Preventing Function Re-Creation:
Optimizing Expensive Operations.
React.memo:
react.memo() is a higher-order component, if have one
component that takes a component as a prop and returns a
component that prevents a component from re-rendering if the
props (or values within it) have not changed.
Diff:
React.memo() is used to memoize entire components to prevent
unnecessary re-renders based on props comparison, while
useMemo() is used to memoize specific values or computations
within a component to optimize performance
Useref:
ref’s are the way to access the dom elements created in the render method.
they are helpful when we want to update the component whith out using state
and props and prevents triggering rerender.
Useref is used to reference a value that’s not need for rendering , if you
rendering of the component does not depends upon this value of this dom
element.
Common useCases:
forward:
forwardref is a technique which is used to send the ref from parent component
to one of its children. This is helpful when we want to access the child
component dom node from the parent component.
import React, { forwardRef } from 'react';
const ChildComponent = forwardRef((props, ref) => {
return <input ref={ref} />;
});
export default ChildComponent;
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
},
clear: () => {
inputRef.current.value = '';
}
}));
function ParentComponent() {
const inputRef = useRef(null);
return (
<div>
<ChildComponent ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>Focus</button>
<button onClick={() => inputRef.current.clear()}>Clear</button>
</div>
);
}
export default ParentComponent;
useId:
basically useid is used to generating unique IDS that can be passed to
accessibility attributes,
these attributes specify two tags are related to each other where you can use
useId generated id instead of hardcodeing them.
import { useId } from 'react';
return (
<div>
<label htmlFor={id}>Username</label>
<input id={id} type="text" />
</div>
);
};
usetransition:
it is used to update the state without blocking the ui ,mean while here showing
loader , it accepts two parameter one is ispending and starttranstion.
import React, { useState, useTransition } from 'react';
function MyComponent() {
const [data, setData] = useState(null);
const [isPending, startTransition] = useTransition();
return (
<div>
<button onClick={fetchData}>Fetch Data</button>
{isPending && <div>Loading...</div>}
{data && <div>Data: {JSON.stringify(data)}</div>}
</div>
);
}
While this manual approach achieves the same result, it might not be as
optimized or efficient as using startTransition, especially in more complex
scenarios with multiple asynchronous updates or frequent state changes.
startTransition takes care of batching and scheduling state updates in an
optimized way, which can lead to better performance and responsiveness in
your React application.
Uselayouteffect:
Runs synchronously after render but before DOM update.
also accepts a dependencies array, but its behavior is more synchronous.
Perform side effects that are related to the layout of the component, such as
setting the position or size of an element
Mixins:
Mixins are a way to totally separate components to have a common
functionality. Mixins should not be used and can be replaced with higher-order
components or decorators.
One of the most commonly used mixins is PureRenderMixin. You might be using
it in some components to prevent unnecessary re-renders when the props and
state are shallowly equal to the previous props and state:
Fragment:
React fragments allows us to wrap or group multiple elements without
adding extra nodes to the dom.
Using : <> </>
Profiler:
It measures how many times the react Application is rendered and how
much time the components take to be rendered. It helps to identify the
parts of the application that are slow so that the developer can optimize
it for better performance. It is lightweight and no third-party dependency
is required.
<Profiler id="" onRender={callback function}>
{Children}
</Profiler>
Lets take one application with in this multiple components with in this
components we can perform various operations .
Lets assume with in this some component is not very responsive after
user performance various operations within this component.
Now we have to identify the root cause for this we should fix this issue .
Our components gets re-render for various operations ,now identify
which component is getting re-render how many times the amount of
time it is taking for re-rendering.
Here we will make use of profiler in react.
So here profiler requires two properties one is Id and second one is on-
render callback .so on-render callback each time a component with in
tree commits and updates.
With in the call back function we can pass various parameters like id
:string,phase:”mount”,|
“upadate”,startTime,commiteTime,actualduration ,and baseduration.
Portals :
Portals are the way to render the child components outside of the
parent’s dom.
ReactDOM.createPortal(child, container);
Lifting state:
Lets consider two components A and B here when you got change in the A
then it will reflect to B vice versa also this called the lifting state.
When several components need to share the same changing data then it
is recommended to lift the shared state up to their closest common
ancestor. That means if two child components share the same data from
its parent, then move the state to parent instead of maintaining local
state in both of the child components.
Errorboundaries:
Controlled vs uncontrolled:
In controlled components, the form data is handled by the react component
We use event handlers to update the state.
React state is the source of truth.
In uncontrolled components, the form data is handled by the dom.
We use Ref’s to update the state.
Dom is the source of truth.
import React from 'react';
const App = () => {
let name = React.createRef();
let age = React.createRef();
const submit = () => {
console.log(name.current.value);
console.log(age.current.value);
};
return (
<div>
<input type="text" placeholder="name" ref={name} />
<input type="text" placeholder="age" ref={age} />
<button type="submit" onClick={submit}>
{' '}
submit
</button>
</div>
);
};
export default App;
createelement vs cloneelement:
jsx elements will be transpiled to React.createElement() functions to create
React elements which are going to be used for the object representation of UI.
Whereas cloneElement is used to clone an element and pass it new props.
spa:
SPA stands for Single Page Application . It's a type of web application or website that
interacts with the user by dynamically rewriting the current web page rather than loading
entire new pages from the server. In other words,
a single HTML page is loaded initially, and then the content is updated dynamically as the
user interacts with the application, typically through JavaScript.
characteristics of SPAs include:
Dynamic Updates - In SPAs, content is loaded and updated without requiring a full
page reload. This is achieved using JavaScript and client-side routing.
Smooth User Experience - SPAs can provide a smoother and more responsive user
experience because they can update parts of the page without the entire page
needing to be refreshed.
Client-Side Routing - SPAs often use client-side routing to simulate traditional page
navigation while staying on the same HTML page. This is typically achieved using
libraries like React Router or Vue Router
handle and optimize large data sets :
Firstly, I would implement pagination or infinite scrolling techniques to load and
display data in smaller chunks, enhancing the performance and usability of the
application. Secondly, I would leverage techniques like virtualization or lazy
loading to render only the visible data, reducing the computational and memory
requirements. This is particularly beneficial when dealing with long lists or grids.
Additionally, I would leverage browser APIs like IndexedDB or WebSQL to store
and retrieve data locally, minimizing the reliance on frequent server requests
Customhook:
creating a custom hook is not mandatary thing but its very good thing
because that will make code looks more good readable ,that will make
your code modular that will make your code more reusable.
Basically it’s a java script function whose name starts with ‘use’.
This hooks can also call other hooks if required.
This hooks is used to share logic between two or more components .
Its is alternative to higher order and renderprops.
Custom hooks provide a more integrated approach within React,
leveraging React's lifecycle and state management features. While regular
JavaScript functions can achieve similar outcomes, custom hooks offer
advantages in terms
Less full:
If the behaviour of a component is independent of its state then it can be a
stateless component. You can use either a function or a class for creating
stateless components. But unless you need to use a lifecycle hook in your
components, you should go for function components. There are a lot of benefits
if you decide to use function components here; they are easy to write,
understand, and test, a little faster, and you can avoid the this keyword
altogether
If the behaviour of a component is dependent on the state of the component
then it can be termed as stateful component. These stateful components are
either function components with hooks or class components.
Let's take an example of function stateful component which update the state
based on click event,
return (
<>
<button onClick={handleIncrement}>Increment</button>
<span>Counter: {count}</span>
</>
)
}
optimize:
mostly we have 12 techniques optimize our react app.
Code Splitting: Break down large bundles into smaller chunks to reduce initial
load times
Suspense:
The lazy loaded components are wrapped by Suspense.The Suspense
component receives a fallback prop which is displayed until the lazy loaded
component in rendered.
r18:
concurrency:
You know in react once the rendering is started ,we can’t interrupt ,we cant
stop the rendering, but after r18 we can pause the rendering ,and also resume
with help of concurrency.
Automatic batching:
multiple state updates into a single re-render for better performance.
Compoundcomponents:
React where multiple components are structured together to share the same
implicit state, facilitating communication between them in the background. This
pattern is particularly useful when building components like accordions,
dropdowns, or selects, where various parts of the component need to interact
with each other seamlessly. Compound components offer a clean and organized
way to manage complex interactions within a component while maintaining a
cohesive and intuitive user experience.
syntheticevents:
You know synthetic events to create a consistent behavior across
different browsers. Unlike regular HTML events, synthetic events are
standardized and behave the same way in all browsers. This provides a
unified event system, making event handling work reliably no matter
which browser is used.
If you want go to any browser they want to maintain same event, it
should work in the same way to solve this purpose what they have done
is they have come up with their own concept called .
function BookStore() {
handleTitleChange(e) {
console.log('The new title is:', e.target.value);
// 'e' represents synthetic event
const nativeEvent = e.nativeEvent;
console.log(nativeEvent);
e.stopPropogation();
e.preventDefault();
}
Corserror:
It stands for cross-origin resource sharing.
It is a security feature that allows the webapplications from one domain to
Authentication:
Its the process of verifying who the user is.
Authorization:
Its the process of verifying what they have access to. What files and data user
has access to.
Good Reference: https://www.youtube.com/watch?v=7Q17ubqLfaM
The user logs in by sending their credentials to the server.
The server verifies the credentials and, if valid, generates a JWT containing the
user’s information.
The JWT is signed with a secret key that only the server knows, ensuring that
the token cannot be tampered with.
The server sends the JWT back to the client, which stores it (in a cookie,
localStorage, etc.).
For every subsequent request, the client includes the JWT in the request
headers.
The server verifies the JWT by checking its signature (using the secret key) and
then reads the user information directly from the token to determine if the user
is authorized to access the requested resource.
JWT
A JWT consists of three parts:
Header: Contains metadata about the token, including the signing algorithm
used.
Payload: Contains the user information (claims) like the user ID, expiration time,
etc.
Signature: A hash of the header and payload, created using the server's secret
key. This ensures the token’s integrity.
Cdn: content delivery network these are the website where does react has
been hoisted and just we are pulling react from their our project.
Production mode:
Dependancies:
There are 2-types of .
1.devdependancie:
It is generally required for in our development.
When we are developing our app then we required for dev
dependencies.
2.Normal dependencies.
Normal dependencies used in production also.
Nodemodules:
Node modules is kind of like data base it contain the actual data
of that dependencies of those packages project needs.
Node modules fetches the all the code of all dependncencies into
our system.
gitIgnore:
If you want to some files not in going to production we can put
gitignore.
Should I put package.json and packge lockJson on to git.
Yes you know these two maintain what all dependencies project
needs.
Treeshaking:
Tree shaking is a process of removing the unwanted code that we do not
use while developing the application. In computing, tree shaking is a dead
code elimination technique that is applied when optimizing code
It reduces the bundle size by eleminating unused modules and functions.
Faster load time. Performance will be improved. Cleaner and
maintainable codebases.
Git:
Set user information:
git config --global user.name "Your Name"
git config --global user.email [email protected]
Initialize a new repository:
git init
Clone a repository:
git clone <repository_url>
Check status:
git status
Add changes for commit:
git add <file(s)>
Commit changes:
git commit -m "Your commit message"
Pull changes from a remote repository:
git pull origin <branch_name>
Push changes to a remote repository:
git push origin <branch_name>
Create a new branch:
git branch <branch_name>
Switch to a branch:
git checkout <branch_name>
Create and switch to a new branch:
git checkout -b <new_branch_name>
List all branches:
git branch
Delete a branch:
git branch -d <branch_name>
Merge changes from another branch:
git merge <branch_name>
Add a remote repository:
git remote add <remote_name> <repository_url>
List remote repositories:
git remote -v
Show commit history:
git log
Discard changes in working directory:
git checkout -- <file(s)>
Undo last commit (keep changes in working directory):
git reset HEAD~
Undo last commit (discard changes):
git reset --hard HEAD~
Stash changes (temporarily save changes):
git stash
Apply stashed changes:
git stash apply
architecture:
Monolithic :
The web browser communicates with front-end monolith application
which communicates with backend Api services that interact with the
database.
Here all the components are tightly coupled and interact directly with
each other if any change one part of the front end module can effect on
the other parts of the application. Scaling this kind of application little
challenging ,
Micro frontend :
Here the web browser communicates micro-front-end shell which is
responsible for loading and managing the various micro front-end
applications .
U know here each of them interacting a particular services of their needs
so here a single owner is not responsible for any change in front end
application.
Identify the different parts of the application that can be divided into
smaller independent parts.
reactdesignpatterns:
cicd:
Continuous Integration (CI) means frequently combining code changes
with automated testing to catch mistakes early. Continuous
Deployment (CD) is about automatically releasing these changes to
users, making the process faster and more reliable.
.
csr:
In csr, rendering occurs on the client side after receiving raw data from
the server
csr has slow initial load time as browser needs to interpret the data and
render the page
subsequent interactions in csr involves dynamic updates with out
requiring full page reload.
Redux:
Principles:
Redux follows three fundamental principles:
Single source of truth: The state of your whole application is
stored in an object tree within a single store. The single state
tree makes it easier to keep track of changes over time and
debug or inspect the application.
State is read-only: The only way to change the state is to emit an
action, an object describing what happened. This ensures that
neither the views nor the network callbacks will ever write
directly to the state.
Changes are made with pure functions: To specify how the state
tree is transformed by actions, you write reducers. Reducers are
just pure functions that take the previous state and an action as
parameters, and return the next state.
mapStateToProps() :
mapStateToProps() is a utility which helps your component get
updated state (which is updated by some other components).
const mapDispatchToProps = {
onTodoClick,
};
Can I dispatch an action in reducer?
Dispatching an action within a reducer is an anti-pattern. Your reducer
should be without side effects, simply digesting the action payload
and returning a new state object. Adding listeners and dispatching
actions within the reducer can lead to chained actions and other side
effects.
How to access Redux store outside a component?
You just need to export the store from the module where it created
with createStore(). Also, it shouldn't pollute the global window
object.
store = createStore(myReducer);
function mapStateToProps(state) {
return { containerData: state.data };
}
state = undefined;
}
context vs redux:
You can use Context in your application directly and is going to be
great for passing down data to deeply nested components which what
it was designed for.
Whereas Redux is much more powerful and provides a large number
of features that the Context API doesn't provide. Also, React Redux
uses context internally but it doesn't expose this fact in the public API.
Why are Redux state functions called reducers?
Reducers always return the accumulation of the state (based on all
previous and current actions). Therefore, they act as a reducer of
state. Each time a Redux reducer is called, the state and action are
passed as parameters. This state is then reduced (or accumulated)
based on the action, and then the next state is returned. You could
reduce a collection of actions and an initial state (of the store) on
which to perform these actions to get the resulting final state.
How to make AJAX request in Redux?
You can use redux-thunk middleware which allows you to define
async actions.
Let's take an example of fetching specific account as an AJAX call using
fetch API:
function setAccount(data) {
return { type: "SET_Account", data: data };
}
Keep your data in the Redux store, and the UI related state internally
in the component.
What is the proper way to access Redux store?
The best way to access your store in a component is to use the
connect() function, that creates a new component that wraps around
your existing one. This pattern is called Higher-Order Components,
and is generally the preferred way of extending a component's
functionality in React. This allows you to map state and action
creators to your component, and have them passed in automatically
as your store updates.
Let's take an example of component using connect:
class MyComponent {
someMethod() {
doSomethingWith(this.context.store);
}
}
Component vs container in React Redux?
Component is a class or function component that describes the
presentational part of your application.
Container is an informal term for a component that is connected
to a Redux store. Containers subscribe to Redux state updates
and dispatch actions, and they usually don't render DOM
elements; they delegate rendering to presentational child
components.
constants in Redux?
Constants allows you to easily find all usages of that specific
functionality across the project when you use an IDE. It also prevents
you from introducing silly bugs caused by typos – in which case, you
will get a ReferenceError immediately.
Normally we will save them in a single file (constants.js or
actionTypes.js).
In reducers:
Let's create reducer.js:
{
user: "john";
}
redux-saga?
redux-saga is a library that aims to make side effects (asynchronous
things like data fetching and impure things like accessing the browser
cache) in React/Redux applications easier and better.
It is available in NPM:
mental model:
Saga is like a separate thread in your application, that's solely
responsible for side effects. redux-saga is a redux middleware, which
means this thread can be started, paused and cancelled from the main
application with normal Redux actions, it has access to the full Redux
application state and it can dispatch Redux actions as well.
function* fetchUserSaga(action) {
// 'call' function accepts rest arguments, which will be passed to 'api.fetchUser' function.
// Instructing middleware to call promise, it resolved value will be assigned to 'userData' variable
const userData = yield call(api.fetchUser, action.userId);
Redux Thunk:
Redux Thunk middleware allows you to write action creators that
return a function instead of an action. The thunk can be used to delay
the dispatch of an action, or to dispatch only if a certain condition is
met. The inner function receives the store methods dispatch() and
getState() as parameters.
redux-saga vs redux-thunk?
Both Redux Thunk and Redux Saga take care of dealing with side
effects. In most of the scenarios, Thunk uses Promises to deal with
them, whereas Saga uses Generators. Thunk is simple to use and
Promises are familiar to many developers, Sagas/Generators are more
powerful but you will need to learn them. But both middleware can
coexist, so you can start with Thunks and introduce Sagas when/if you
need them.
Redux DevTools:
Redux DevTools is a live-editing time travel environment for Redux
with hot reloading, action replay, and customizable UI. If you don't
want to bother with installing Redux DevTools and integrating it into
your project, consider using Redux DevTools Extension for Chrome
and Firefox.
Some of the main features of Redux DevTools are below,
Lets you inspect every state and action payload.
Lets you go back in time by cancelling actions.
If you change the reducer code, each staged action will be re-
evaluated.
If the reducers throw, you will see during which action this
happened, and what the error was
With persistState() store enhancer, you can persist debug
sessions across page reloads.
Selectors:
Selectors are functions that take Redux state as an argument and
return some data to pass to the component.
For example, to get user details from the state:
const initialState = {
todos: [{ id: 123, name: "example", completed: false }],
};
flow
1. Define Actions:
Define action types and create action creator functions.
2. Define Reducers:
Write reducer functions to handle actions and update state.
3. Combine Reducers:
Use combineReducers to combine reducers into a single
rootReducer.
4. Create Store:
Create Redux store using createStore with the rootReducer.
5. Connect Redux Store:
Wrap the root component with <Provider> from react-redux.
Pass the Redux store as a prop to <Provider>
unit testing:
Unit testing is nothing but you test your react
component is isolation.
Whenever you testing ui component inside react, you
will have render that component on the jsdom.
Integration testing:
We have application there are so many components the
components talk to each other like collaborate ,here we
will develop a flow of an action in react app that we will
test.
e2e:
end to end testing means as soon as the user lands on the
website ,we will test all the flows.
Jsdom:
When you run test cases there is no server running there is no
browser, these test cases does not run on browser, they will
need environment to run .these test cases will be executed .
accessibility:
Next js:
Next.js and React.js in terms of rendering, routing, SEO,
performance, deployment, and API routes, helping developers
choose the right tool for their needs.
React is a JavaScript library for building user interfaces,
primarily focused on the component-based architecture. It
provides the tools to build the UI, manage state, and handle
component lifecycle, but it doesn't manage how to handle
routing, data fetching, or server-side rendering. Optimizing.
Next.js is a framework built on top of React. It extends React's
capabilities .
webworker-
Imagine a restaurant with multiple chefs working together to
prepare a meal. Each chef has their own workstation, and
they work independently to complete their tasks. When a dish
is ready, they pass it to the next chef, who then works on their
portion of the meal.
In this example, each chef represents a Web Worker. A Web
Worker is a script that runs in the background, independent of
the main thread (the "kitchen" where the main application
code runs). Web Workers are used to perform tasks that are
computationally intensive, such as data processing, image
compression, or complex calculations. By offloading these
tasks to a separate thread, the main application remains
responsive and doesn't freeze or become unresponsive.
serviceworker-
Now, imagine a delivery service that takes orders from
customers and delivers them to their doorstep. The delivery
service acts as an intermediary between the customer and the
restaurant, ensuring that the order is fulfilled correctly and
efficiently.
In this example, the delivery service represents a Service
Worker. A Service Worker is a script that runs in the
background, but it's not just a simple script – it's a script that
acts as a proxy between the client-side application and the
server. Service Workers are used to handle network requests,
cache resources, and provide offline support to web
applications.