Naan Mudhalvan Upskilling Platform
A massive industry relevant skill enhancement initiative for the Youth of Tamil Nadu.
 WEEK 1 – PROGRAM ORIENTATION
 ● Introduction to React, Overview of React.js
 ● Creating a basic React Component
 ● Understanding props and State
React Basics and Component ● Building Reusable React Components
Architecture ● Managing Component Lifecycle
 ● Conditional Rendering and Event Handling
 ● State Updates and Re-Renders
 ● Event Loop, Memoization for Performance
 WEEK 9,10- USE CASES AND PROJECT
 Optimization
 FINAL
 SUBMISSION AND EVALUATION.
 Introduction to React
● React JS is an adaptable JavaScript library for creating user interfaces, especially for building single-page
 applications.’
● It was initially developed and is still maintained by Facebook.
● React's ability to dynamically update and render data without requiring full-page reloads enhances the performance
 and responsiveness of web applications.
● An example for this can be search bar of an amazon application, where, when user types in the search field, React can
 update the search results in real time by dynamically fetching and rendering matching products without reloading the
 entire page.
● This can be achieved using onChange events, useStates of react.
 Features of React
● JSX (JavaScript Syntax Extension):
 JSX lets you write HTML-like code in JavaScript. It’s compiled by tools like Babel into standard JavaScript.
 Example:
● const user = "Siri";
 const greeting = <h2>Hello, {user}!</h2>;
● Virtual DOM:
 React uses a lightweight copy of the real DOM to detect and apply only the necessary changes, improving performance.
● One-way Data Binding:
 Data flows from parent to child components. Children can't directly change parent data, ensuring better control and stability.
 Features of React
● Performance:
 React updates only what's needed, making apps faster. Its component-based structure enhances efficiency and
 scalability.
● Extension:
 React supports extensions like Redux (state management) and React Native (mobile development).
● Simplicity:
 Component-based architecture and JSX make development clean, modular, and easy to debug.
● Components:
 Reusable, self-contained units that handle their own logic and UI, making development faster and more
 organized.
 .
ReactJs Architecture
 ReactJs Architecture
● Component-Based Architecture:
 React builds UIs using reusable, self-contained components that manage their
 own logic and state.
● JSX:
 A syntax extension that allows writing HTML-like code in JavaScript,
 making UI code more readable and dynamic.
● Virtual DOM:
 React creates a virtual copy of the real DOM. When state changes, it
 compares the new virtual DOM with the previous one and updates only the
 changed parts in the real DOM, improving performance.
● Types of Components:
 Functional Components: Defined using functions. Use Hooks like useState
 and useEffect for state and side effects.
● Class Components: Older, ES6-style components with lifecycle methods
 (now less commonly used).
 ReactJs Architecture
● State Management:
 Components manage their own state. Hooks like useState and useEffect help handle state and side effects like API calls.
● One-Way Data Binding:
 Data flows from parent to child via props. Props are read-only, ensuring predictable behavior.
● Example:
 function Apple(props) {
 return <p>{props.message}</p>;
 }
 function Fruit() {
 return <Apple message="Apple is rich in Vitamin C" />;
 }
● Redux (External Library):
 Centralizes and manages application state, useful for large apps with complex data flows.
● Context API:
 Shares global data across components without prop drilling.
● React Router:
 Handles routing and enables single-page application (SPA) navigation without full page reloads.
 JSX
JSX is JavaScript XML which is the syntax extension for JavaScript that look similar to HTML
but is the react library which allows to to write HTML structures along with JavaScript code
basically combining both the languages capabilities. This JSX is transpiled into the regular
JavaScript language using the Babel tools that helps browsers to interpret JSX.
 Example for JSX:
 const element = <h1>Hello This is JSX Syntax</h1>;
 The above same example is translated as:
 const element = React.createElement('h1', null, 'Hello This is JSX Syntax ');
 Advantages of JSX:
● Once familiar with HTML it is easy to use JSX in
 React components.
● This is helpful for large applications with huge
 codes
● JSX allows you to write components in a more
 readable, declarative format. Since it closely
 resembles HTML and makes it easy to understand
 how the UI should look.
● JSX encourages building reusable UI components.
 Each component can be written as a self-contained
 function or class, making it easier to manage and
 test.
● Since JSX allows embedding JavaScript directly,
 developers can use debugging tools to step
 through code, set breakpoints, and catch errors
 more effectively.
 Creating a basic React Component
 ● The React component
 can be created using
 following basic
 command:
npx create-react-app my-
react-app
 ● After this , the project
 folder named my-react-
 app is created, change
 directory to my-react-
 app.
Then, to start this application
use, npm start.
Creating a basic React Component
Creating a basic React Component
 Open new terminal and run npm start:
The default react app will load at port 3000.
The new component can be created and imported to app.js to host the custom
component, for example lets create new js file with custom code and import it
from app.js file:
Open the browser after npm start,
 Understanding props and State
 The Props and States in react are useful for managing the passage of data from
 components that helps in building dynamic and interactive User Interfaces.
Props:
● Props in react are short form for properties which are used to pass data from
 parent component to child component
● These props are read only in which, the child component cannot change these
 properties received from parent component. That is, props are immutable.
● Generally the props are passed from parent component in the way of adding
 attributes to the component’s tag in JSX, which the child component can access
 using ‘this.props’ or directly as function parameters.
✅ ProfileCard with Props Example
📁 App1.js (Using ProfileCard)
import React from "react";
function ProfileCard(props) {
 return (
 <div>
 <h2>{props.name}</h2>
 <p>{props.bio}</p>
 <p>Email: {props.email}</p>
 </div>
 );
}
function App1() {
 return (
 <div>
 <ProfileCard
 name="Siri"
 bio="Software Engineer"
 email="iamsiri@gmail.com"
 />
 </div>
 );
}
export default App1;
📁 App.js (Main Entry Point)
import React from "react";
import App1 from "./App1"; // Ensure filename matches
const App = () => {
 return (
 <div>
 <App1 />
 </div>
 );
};
export default App;
 States:
● The states in react are internal objects
 which are used to hold data or
 properties, so that state will store the
 internal data that can change within
 the component.
● During the change of state during user
 interactions or api calls, of
 component, react will re-render the
 component with updated data.
● The state can be only get updated in
 the component where it is defined but
 not in other components.
● The updation of this state is generally
 done using setState, useState()
 methods, therefore states are mutable.
📁 state.js (Using useState)
import React, { useState } from "react"; // ✅ Corrected useState
function NameForm() {
 const [name, setName] = useState("");
 return (
 <div>
 <input
 type="text"
 placeholder="Please enter your name"
 value={name}
 onChange={(e) => setName(e.target.value)}
 />
 <p>Your name is: {name}</p>
 </div>
 );
}
export default NameForm;
📁 App.js (Main App)
import React from "react";
import NameForm from "./state"; // ✅ Make sure filename is correct
const App = () => {
 return (
 <div>
 <NameForm /> {/* ✅ Properly closed */}
 </div>
 );
};
export default App;
 Building Reusable React Components
Reusable components are
components that can be used in
multiple places within your app
without rewriting them.
These include UI elements like
buttons, inputs, headers, etc.
Reusability helps:
● Reduce duplicate code
● Improve maintainability and
 readability
● Make the app scalable
 Managing Component Lifecycle
● The component lifecycle in React has different
 phases in which the component will go through
 phases from creation to end.
● There are some lifecycle methods and hooks that
 react provides to manage the phases.
● The Lifecycle can also be thought as side-effect for
 example, after adding item to a cart that is one
 action, we expect a notification for added item that
 is side-effect for the previous action which is a part
 of lifecyle.
● There is only one side-effect in Functional
 component in React that is useEffect(), that is one
 react Hook.
 Class Component Lifecycle Methods
1
1️⃣ constructor()
✅ What it does:
 ● Called first when the component is initialized
 ● Used to set initial state and bind methods
✅ Example:
class MyComponent extends React.Component {
 constructor(props) {
 super(props);
 this.state = { count: 0 };
 this.handleClick = this.handleClick.bind(this); // binding method
 }
}
2️⃣ render()
✅ What it does:
 ● Required method in class components
 ● Returns JSX to be rendered on the screen
✅ Example:
render() {
 return <h1>Count: {this.state.count}</h1>;
}
3
3️⃣ componentDidMount()
✅ What it does:
 ● Runs after the component is mounted (added to the DOM)
 ● Used for API calls, subscriptions, timers, or DOM access
✅ Example:
componentDidMount() {
 console.log("Component mounted");
 fetchData();
}
4️⃣ shouldComponentUpdate(nextProps, nextState)
✅ What it does:
 ● Runs before re-render
 ● Use to optimize performance
 ● Return false to prevent re-render
✅ Example:
shouldComponentUpdate(nextProps, nextState) {
 return nextState.count !== this.state.count;
}
5️⃣ getDerivedStateFromProps(props, state)
✅ What it does:
 ● Static method
 ● Runs before render during mount and update
 ● Used to sync state with props
 ✅ Example:
static getDerivedStateFromProps(nextProps, prevState) {
 if (nextProps.value !== prevState.value) {
 return { value: nextProps.value };
 }
 return null;
}
6️⃣ componentDidUpdate(prevProps, prevState, snapshot)
✅ What it does:
 ● Called after component updates (i.e., after re-render)
 ● Used for side effects after state/prop change]
 ✅ Example:
componentDidUpdate(prevProps, prevState) {
 if (prevState.count !== this.state.count) {
 console.log("Count updated:", this.state.count);
 }
}
7
7️⃣ getSnapshotBeforeUpdate(prevProps, prevState)
✅ What it does:
 ● Captures DOM values (like scroll position) before update
 ● Runs between render() and componentDidUpdate()
✅ Example:
getSnapshotBeforeUpdate(prevProps, prevState) {
 if (prevProps.message !== this.props.message) {
 return this.divRef.scrollTop;
 }
 return null;
}
8️⃣ componentWillUnmount()
✅ What it does:
 ● Runs before component is removed from DOM
 ● Used for cleanup: clear timers, unsubscribe listeners, etc.
 ✅ Example:
componentWillUnmount() {
 console.log("Component will be removed");
 clearInterval(this.timer);
}
 Conditional Rendering and Event Handling
🔍 What is Conditional Rendering?
Conditional rendering means showing different UI elements depending on a condition or application state. It’s
useful for:
 ● Hiding/showing components based on user actions
 ● Rendering different views (e.g., login vs. dashboard)
 ● Improving performance by avoiding unnecessary DOM rendering
🧠 Techniques for Conditional Rendering
▶️Using Ternary Operator
function MyGreetings(props) {
 const isLoggedIn = props.isLoggedIn;
 return (
 <div>
 {isLoggedIn ? <h1>Hey, Welcome back!</h1> : <h1>How are you?</h1>}
 </div>
 );
}
export default MyGreetings;
▶️Using Logical && (Short-circuit evaluation)
function Greeting(props) {
 const isLoggedIn = props.isLoggedIn;
 return <div>{isLoggedIn && <h1>Hey, Welcome back!</h1>}</div>;
}
export default Greeting;
Note: isLoggedIn && <h1>...</h1> means:
If is LoggedIn is true, show <h1>; otherwise, render nothing.
2. Event handling:
● Event handling in React is similar to how you handle events in JavaScript, with
 a few syntactical differences.
● In React, events are named using camelCase, and you pass event handlers as
 functions rather than strings. There are few basic principles that align with
 react’s few basic principles that align with its component-based architecture
These are few principles like :
Synthetic event system, Naming conventions, Passing event handlers as props and
Inline function and component methods
->The synthetic event system that ensures events behave consistently across
different browsers.
🔹 Synthetic Event Example
function InputLogger() {
 function handleInputChange(event) {
 console.log("Synthetic:", event);
 console.log("Native:", event.nativeEvent);
 }
 return <input type="text" onChange={handleInputChange} />;
}
🔹 Naming Convention
 ● Handlers usually follow handleEventName format (e.g., handleClick)
 ● Defined above return and can be passed as props or used inline
 Common Event Types
🔹 Event Handling Example ● Form: onChange, onSubmit
import React, { useState } from "react"; ● Mouse: onClick, onMouseEnter,
 onDrag
function ClickCounter() {
 const [count, setCount] = useState(0); ● Keyboard: onKeyDown, onKeyUp
 function handleClick() {
 setCount(count + 1);
 }
 return (
 <div>
 <button onClick={handleClick}>Click me</button>
 <p>Clicked {count} times</p>
 </div>
 );
}
 Passing Arguments to Event Handlers
Passing arguments to event handlers in React is a common requirement when you need to
perform actions on specific data associated with an event. For example, deleting or editing a
resource.
This can be achieved by
1. Arrow functions
Example:
const handleClick = (item) => {
console.log('Button click for:', item);
};
<button onClick={() => handleClick(item)}>Here</button>
2. Passing Arguments Using .bind()
function ClickButton() {
const handleclick = (name) => {
alert('Hey Hello, ${name}! ');
};
return <button onClick={handleclick.bind(null, "Riya")}>Greet</button>;
}
export default ClickButton;
 Efficient use of Event Handling
 1. Avoid Inline Event Handlers in JSX
 Defining event handlers directly in JSX can lead to unnecessary re-renders because a
 new function is created each time the component re-renders.
 Therefore for example, instead of this
 <button onClick={() => this.handleClick()}>Click Me</button>
 We use this
 <button onClick={this.handleClick}>Click Me</button>
2. Use useCallback for Stable References in Functional Components
In functional components, if an event handler depends on props or state, it may get recreated on each render. This can
be avoided with useCallback in functional components, which memoizes the function and keeps the same reference
across renders (until dependencies change).
 Example:
 import { useCallback, usestate } from "react";
 function MyComponent({ someProp }) {
 const [count, setCount] = usestate(0);
 const handleClick = useCallback(() => {
 setCount(count + 1);
 }, [count]);
 return <button onclick={handleclick}>click {count}</button>;
 }
 export default MyComponent;
3. Using Prevent Default Behavior
 ● Use event.preventDefault() in your event handlers when you need to stop the browser from
 performing default actions, like submitting a form.
 ● For example, to prevent the browser from refreshing when a form is submitted, or prevent any
 other default behavior, pass the event parameter into the function handling the onSubmit
 event, then use that event to call a preventDefault function.
Example app3.js:
import React, { useState } from "react";
function FormComponent() {
const [inputvalue, setInputValue] = useState("");
const handleInputChange = (event) => {
setInputvalue(event.target.value);
};
const handleSubmit = (event) => {
event. preventDefault();
console.log("Form submitted with input:", inputvalue);
 placeholder="Enter something ... "
setInputValue("");
 />
};
 <button
return (
 type="submit">Submit</button>
<form onSubmit={handleSubmit}>
 </form>
<input
 );
type="text"
 }
value={inputValue}
 export default FormComponent;
onchange={ handleInputChange}
4. Clean Up Event Listeners:
If we use event listeners in useEffect, always return a cleanup
function to remove the event listener. Otherwise, it'll cause memory
leaks.
Example without cleaning functions:
import React, { usestate, useEffect } from "react";
function Timer() {
const [count, setCount] = usestate(0);
useEffect(() => {
const intervalId = setInterval(() => {
setCount((prevCount) => prevCount +1);
}, 1000);
}, []);
return <div>Count: {count}</div>;
}
export default Timer;
Using cleanup function:
import React, { usestate, useEffect } from "react";
function Timer() {
const [count, setCount] = usestate(0);
useEffect(() => {
const intervalId = setInterval (() => {
setCount((prevCount) => prevCount + 1);
}, 1000);
return () => {
//here is the cleanup happening
clearInterval(intervalId);
}, []);
return <div>Count: {count}</div>;
}
export default Timer;
5. Event Propagation
Use event.stopPropagation() to stop bubbling up to parent handlers.
const handleClick = (e) => {
 e.stopPropagation();
 alert("Child clicked!");
};
6. Conditional Event Handling
Run events only when certain conditions are met.
if (isEnabled) {
 // handle click
}
 State Updates and Re-Renders
In React, state updates and component re-renders are foundational concepts. When
state changes, React re-renders the component to reflect the new data in the UI.
📦 What is State?
● State represents dynamic data that can change over time within a
 component.
● Updating state triggers a re-render to keep the UI in sync with the
 internal data.
● In functional components, state is managed with the useState hook.
● In class components, it's managed using this.setState.
⚙️Functional Component with useState
import React, { useState } from "react";
function Counter() {
 const [count, setCount] = useState(0);
const increment = () => {
 setCount(count + 1);
 };
return (
 <div>
 <p>Count: {count}</p>
 <button onClick={increment}>Increment</button>
 </div>
 );
}
export default Counter;
 ● count holds the current value.
 ● setCount updates the state and causes a re-render.
🏗 Class Component with this.setState
import React, { Component } from "react";
class Counter extends Component {
 constructor(props) {
 super(props);
 this.state = { count: 0 };
 }
 increment = () => {
 this.setState({ count: this.state.count + 1 });
 };
 render() {
 return (
 <div>
 <p>Count: {this.state.count}</p>
 <button onClick={this.increment}>Increment</button>
 </div>
 );
 }
}
export default Counter;
 ● this.state stores the component's state.
 ● this.setState() updates the state and triggers a re-render
Asynchronous & Batched Updates
React batches multiple state updates together to improve performance. This
means updates might not happen instantly, especially within the same event
handler.
✅ Example using Functional Update:
setCount(prev => prev + 1);
setCount(prev => prev + 1); // Now count will increment by 2
🔁 Example: Batching in Action
import React, { useState } from "react";
function DoubleCounter() {
 const [count, setCount] = useState(0);
 const incrementTwice = () => {
 setCount(prev => prev + 1);
 setCount(prev => prev + 1);
 };
 return (
 <div>
 <p>Count: {count}</p>
 <button onClick={incrementTwice}>Increment Twice</button>
 </div>
 );
}
export default DoubleCounter;
React batches the updates when they're in the same event handler.
Using prev => prev + 1 ensures each update is based on the latest value.
 Re-Renders in React
 ● When a component’s state or props change, React schedules a re-render. This re-
 render process is top-down, meaning:
 ● A parent component's re-render causes its child components to re-render — even
 if their props haven’t changed.
🔁 Re-render Propagation Example
function Parent() {
const [count, setCount] = usestate(0);
return
<div>
<button onclick={() => setCount(count + 1)}>
Increment Parent Count
</button>
<Child count={count} />
</div>
usestate
from "react";
function Child({ count }) {
console.log("Child re-rendered");
return <p>Parent Count: {count}</p>;
export default Parent;
}
Every time the parent updates its count, both Parent and Child re-render — even if count didn’t
change.
🚀 Optimization: Prevent Unnecessary Re-renders with React.memo
React.memo is a higher-order component that tells React to only re-render the component if its
props actually change.
✅ Optimized Version:
import React, { useState } from "react";
function Parent() {
 const [count, setCount] = useState(0);
 return (
 <div>
 <button onClick={() => setCount(count + 1)}>
 Increment Parent Count
 </button>
 <Child count={count} />
 </div>
 );
}
const Child = React.memo(({ count }) => {
 console.log("Child re-rendered");
 return <p>Parent Count: {count}</p>;
});
export default Parent;
 Now, Child only re-renders if count prop actually changes.
If you add other state to the Parent, and update that, Child won’t re-render unless its own
prop changes.
 Event Loop
● The event loop is a mechanism that allows JavaScript to
 perform non-blocking operations. Since JavaScript runs in a
 single-threaded environment, it cannot perform multiple tasks
 at the same time.
● The event loop manages asynchronous operations, such as
 timers, network requests, and user events, by utilizing a call
 stack, an event queue, and the callback queue.
🧠 1. Call Stack
❖ The call stack is where functions are executed.
❖ When a function is invoked, it’s pushed onto the stack, and when it returns, it’s
 popped off.
❖ JavaScript executes code synchronously, one function at a time, from the top of the
 stack.
⏳ 2. Asynchronous Operations
❖ Operations like setTimeout, fetch, and Promise-based tasks are asynchronous.
❖ These are non-blocking, so they don’t halt the main thread.
❖ Instead, they are handled by the browser's Web APIs.
🌐 3. Web APIs
 ● Provided by the browser (not JavaScript itself).
 ● Handle asynchronous tasks like:
 SetTimeout
 ○ DOM events
 ○ fetch calls
 ● Once completed, results are returned to:
 ○ Task Queue → for callbacks like setTimeout
 ○ Microtask Queue → for Promise resolutions
4. Event Queue (Callback Queue) and Microtask Queue
 ● These queues hold tasks waiting to be processed.
 ● The Event Loop manages them:
 ○ If the Call Stack is empty, it first processes all tasks in the Microtask Queue.
 ○ Then, it moves on to the Callback Queue (Task Queue).
 ● Microtasks (like .then, .catch, async/await) are prioritized over regular tasks.
 Memoization for Performance Optimization
Memoization is a performance optimization technique where the results of expensive function calls are
cached and reused if the same inputs occur again. This prevents unnecessary computations and re-renders,
improving performance in React applications.
💡 Why Use Memoization?
In React, re-rendering occurs frequently. When a component re-renders:
● All child components re-render too, unless optimized.
● This can lead to performance issues when expensive calculations or large trees are involved.
Memoization helps avoid:
● Unnecessary re-renders
● Redundant calculations
✅ Memoization Techniques in React
1. React.PureComponent (Class Components)
 ● Extends React.Component and implements shallow prop and state comparison in
 shouldComponentUpdate().
 ● Prevents re-render if props/state didn't change.
✅ Example – Child.js
import React, { PureComponent } from "react";
class Child extends PureComponent {
 render()
<div>
{/* Display the color prop */}
<h2>Child Component - Color: {this.props.color}</h2>
</div>
);
}
}
export default Child;
✅ Example – Parent.js
import React, { Component } from "react";
import Child from "./Child";
class Parent extends React.Component {
constructor(props) {
super(props);
this.state={ color: "pink" };
}
changeColor = () => {
this.setState((prevState) => {
return { color: prevState.color ==="red" ? "blue" : "red" };
});
render() {
console.log("Parent render");
return (
<div className="App">
<button onclick={this.changeColor}>Change Color</button>
<h2>Current Color: {this.state.color}</h2>
<Child color={this.state.color} />
</div>
);
}
}
export default Parent;
2. useMemo: Memoizing Expensive Computations
The useMemo hook memoizes the result of a function and recomputes it only when its dependencies
change. It's especially useful when an operation is expensive and shouldn't be recalculated on every render.
Example – memozation2.js
function OptimizedCalculationComponent() {
const [count, setCount] = useState(0); const [text, setText] = useState("");
const calculateDouble = (number) => {
console.log("Performing an expensive calculation...");
return number * 2;
};
const memoizedResult = useMemo(() => {
return calculateDouble(count);
}, [count]);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<p>Count: {count}</p>
<p>Memoized Result: {memoizedResult}</p>
</div>
);
}
export default OptimizedCalculationComponent;
 3. useCallback: Memoizing Functions
 The useCallback hook memoizes function references, preventing them from being recreated on every render
 unless their dependencies change. This is especially useful when passing functions to child components, so
 React.memo can effectively prevent re-renders .
File – memoization.js
import React, { useState, useCallback } from "react";
function Parent() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
const increment = useCallback(() => { setCount(count + 1);
}, [count]);
return(
<div>
<button onclick={increment}>Increment</button>
<Child count={count} />
<input value={text} onChange={(e) => setText(e.target.value)} />
</div>
);
}
const Child = React.memo(({ count }) => {
console.log("Child re-rendered");
return <p>Count: {count}</p>;
});
export default Parent;
 4. React.memo: Optimizing Functional Components
 React.memo is a Higher-Order Component that prevents re-rendering of functional
 components if their props haven’t changed.
File – memo.js
import React, { useState } from "react";
const Child = React.memo(({ count }) => { console.log("Child component rendered"); return
<p>Count: {count}</p>;
});
function Parent() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<Child count={count} />
</div>
export default Parent;