KEMBAR78
Framework and Libraries | PDF | Software Development | Computing
0% found this document useful (0 votes)
46 views43 pages

Framework and Libraries

The document provides an overview of Node.js and React, detailing the setup of a React environment using Create React App and fundamental concepts such as components, JSX, state management, and event handling. It covers key features of Node.js, its architecture, and various use cases, while also explaining React's functional and class components, props, hooks, and lifecycle methods. Additionally, it includes examples of using hooks like useState and useEffect for state management and API data fetching.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views43 pages

Framework and Libraries

The document provides an overview of Node.js and React, detailing the setup of a React environment using Create React App and fundamental concepts such as components, JSX, state management, and event handling. It covers key features of Node.js, its architecture, and various use cases, while also explaining React's functional and class components, props, hooks, and lifecycle methods. Additionally, it includes examples of using hooks like useState and useEffect for state management and API data fetching.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 43

Framework and Libraries

5.1 Introduction of Node.js

5.2 Getting up React environment, Create React App

5.3 Hello World, Components, JSX

5.4 Functional vs class components, Props

5.5 State, Lifecycle methods

5.6 Hooks – useState, useEffect, useContext

5.7 Event handling

5.8 Forms – controlled components, submission,

validation

5.9 Conditional rendering – if, ternary, &&

5.10 Lists and keys, Importance of keys

5.11 Styling – CSS, CSS Modules, CSS-in-JS

5.12 React Router – setup, routes, parameters

5.13 Async/await, Promises, Fetch API

📘 5.1 Introduction to Node.js

Node.js is a JavaScript runtime built on Chrome's V8 engine that


allows you to run JavaScript outside the browser, mainly used for
building server-side applications.

🚀 Key Features of Node.js:

Feature Description

Asynchronous & Handles multiple requests without waiting for one


Non-blocking I/O to finish. Great for scalability.

Event-driven Uses events and callbacks for handling tasks like


architecture reading files or processing HTTP requests.

Single-threaded but Uses a single thread but can handle thousands of


scalable requests using event loop.

Uses Google Chrome’s V8 engine to compile


Fast execution
JavaScript into native machine code.

Cross-platform Runs on Windows, Mac, Linux.


Feature Description

NPM (Node Package Includes over 1.5 million open-source


Manager) packages/libraries for rapid development.

💡 Use Cases of Node.js:

 Web servers & APIs (RESTful services)

 Real-time applications (e.g., chat apps, multiplayer games)

 File system tools

 Microservices

 Command-line tools

🧱 Node.js Architecture:

 V8 Engine – Compiles JS to machine code

 Libuv – Handles asynchronous I/O using an event loop

 Event Loop – Manages incoming events & executes callbacks

 C++ bindings – Interface between JS and OS-level APIs

⚛️Getting Up the React Environment & Creating a React App

To build React apps, you need to set up a development environment first.


The easiest way to start is with Create React App (CRA).

✅ Step-by-Step: Setup React with Create React App

🔧 1. Install Node.js (if not already installed)

React needs Node.js and npm (Node Package Manager).


Download from: https://nodejs.org

Check versions:

node -v

npm -v

⚙️2. Create a New React App

npx create-react-app my-app

 npx is a tool that comes with npm, used to run commands.

 my-app is your project folder name (you can change it).


💡 This sets up everything: React, Webpack, Babel, project structure, etc.

📁 3. Project Structure Overview

my-app/

├── public/
│ └── index.html // Root HTML file
├── src/
│ ├── App.js // Main React component
│ └── index.js // App entry point
├── package.json // Project dependencies and scripts
▶️4. Run Your App

Navigate to your app folder and run:

cd my-app

npm start

 This will open http://localhost:3000 in your browser.

 You'll see the default React welcome screen.

✅ 5. Edit and Build

 Open src/App.js and modify the component to start building your


app.

 To build your project for production:

npm run build

⚛️5.3 Hello World, Components, and JSX in React

✅ 1. Hello World in React

After setting up your React environment using create-react-app, go to:

📄 src/App.js and replace the code with:

import React from 'react';

function App() {

return (

<div>

<h1>Hello World from React!</h1>

</div>
);

export default App;

Then run:

npm start

You’ll see “Hello World from React!” in your browser.

🧱 2. Components in React

➤ What is a Component?

A component is a reusable piece of UI. There are two types:

 Functional Components (most common)

 Class Components (older way)

✅ Functional Component Example:

function Greeting() {

return <h2>Hello from Greeting Component</h2>;

Use it in App.js:

function App() {

return (

<div>

<Greeting />

</div>

);

🔤 3. JSX (JavaScript XML)

JSX is a syntax extension for JavaScript that looks like HTML but is used
in React.

✅ Example of JSX:

const name = "Alice";


const element = <h1>Hello, {name}!</h1>;

It allows embedding JavaScript inside curly braces {}:

function App() {

const name = "Bob";

return <h2>Welcome, {name}</h2>;

💡 JSX Rules:

 Always return a single root element

 Use className instead of class

 Use {} for dynamic content

⚛️4. Functional vs Class Components + Props

In React, you build UI using components, and you pass data between
them using props (properties).

✅ What Are Props?

 Props are short for "properties"

 They allow you to pass data from parent to child components

 Props are read-only

🧩 Functional Component with Props

// GreetingFunctional.js

import React from 'react';

function GreetingFunctional(props) {

return <h2>Hello, {props.name}!</h2>;

export default GreetingFunctional;

✅ You can also use destructuring to simplify:

function GreetingFunctional({ name }) {

return <h2>Hello, {name}!</h2>;


}

🧱 Class Component with Props

// GreetingClass.js

import React, { Component } from 'react';

class GreetingClass extends Component {

render() {

return <h2>Hello, {this.props.name}!</h2>;

export default GreetingClass;

🧪 Using Both in App

// App.js

import React from 'react';

import GreetingFunctional from './GreetingFunctional';

import GreetingClass from './GreetingClass';

function App() {

return (

<div>

<GreetingFunctional name="Alice" />

<GreetingClass name="Bob" />

</div>

);

export default App;

🧾 Output

Hello, Alice! // from functional component

Hello, Bob! // from class component


🆚 Summary Table

Functional
Feature Class Component
Component

class + extends
Syntax Function
React.Component

props.name or
Props Access this.props.name
{ name }

State ✅ useState Hook


✅ this.state & this.setState()
Management (modern)

❌ Legacy / rarely used in new


Recommended ✅ Yes (modern apps)
code

Here’s a simplified explanation of 5.5: State and Lifecycle Methods in


Functional Components using React Hooks (useState, useEffect):

✅ What is State?

 State is a built-in object in React used to store and manage data


inside a component.

 It updates the UI whenever its value changes.

Example: Counter with useState

import React, { useState } from 'react';

function Counter() {

const [count, setCount] = useState(0); // initial state is 0

return (

<div>

<h2>Count: {count}</h2>

<button onClick={() => setCount(count + 1)}>Increment</button>

</div>

);

}
export default Counter;

🔁 What are Lifecycle Methods in Functional Components?

 Functional components use useEffect() instead of lifecycle methods


(like componentDidMount, componentDidUpdate,
componentWillUnmount).

🔹 1. Run once when component mounts (like componentDidMount)

useEffect(() => {

console.log("Component mounted");

}, []); // empty dependency array means only once

🔹 2. Run when state/props update (like componentDidUpdate)

useEffect(() => {

console.log("Count updated");

}, [count]); // runs only when `count` changes

🔹 3. Cleanup before component unmounts (like


componentWillUnmount)

useEffect(() => {

const timer = setInterval(() => {

console.log("Running...");

}, 1000);

return () => {

clearInterval(timer); // cleanup

console.log("Component unmounted");

};

}, []);

Example:

import React, { Component } from 'react';


class StateLifeCycle extends Component {

constructor() {

super();

this.state = { count: 0 };

console.log('Constructor: Component is being created');

componentDidMount() {

console.log('Mounted: Component is on the screen');

componentDidUpdate() {

console.log('Updated: State or props changed');

componentWillUnmount() {

console.log('Unmounting: Component is being removed');

increase = () => {

this.setState({ count: this.state.count + 1 });

render() {

return (

<div>

<p>Count: {this.state.count}</p>

<button onClick={this.increase}>Counter Increment</button>


</div>

);

export default StateLifeCycle;

🧾 Summary

Feature Hook / Concept

Local state useState()

On mount useEffect(() => {}, [])

useEffect(() => {},


On update
[dependency])

On unmount return () => {} inside


(cleanup) useEffect

1. useState Hook

 Purpose: The useState hook allows you to add state to functional


components. It returns an array with two values: the current state
and a function to update the state.

Example: Counter with useState

import React, { useState } from 'react';

function Counter() {

const [count, setCount] = useState(0); // state with initial value 0

return (

<div>

<h2>Count: {count}</h2>
<button onClick={() => setCount(count + 1)}>Increment</button>

<button onClick={() => setCount(0)}>Reset</button>

</div>

);

export default Counter;

 useState(0): Initializes the count to 0. The first value (count) holds


the current state, and setCount is the function to update that state.

 setCount(count + 1): Updates the state by increasing the count.

1. Using useEffect to Fetch API Data

Here, we will use the useEffect hook to fetch data from an API when the
component mounts. For simplicity, we will use the JSONPlaceholder API to
get some sample posts.

Example: Fetching Data from an API with useEffect

import React, { useState, useEffect } from 'react';

function Posts() {

const [posts, setPosts] = useState([]); // State to hold the fetched posts

const [loading, setLoading] = useState(true); // State to track loading


state

// useEffect to fetch data from API when the component mounts

useEffect(() => {

fetch('https://jsonplaceholder.typicode.com/posts')

.then(response => response.json()) // Convert response to JSON

.then(data => {

setPosts(data); // Store the data in state

setLoading(false); // Set loading to false once data is fetched


})

.catch(error => console.error('Error fetching data:', error)); // Error


handling

}, []); // Empty array means this effect runs once when the component
mounts

return (

<div>

<h2>Posts</h2>

{loading ? (

<p>Loading...</p>

):(

<ul>

{posts.map(post => (

<li key={post.id}>{post.title}</li> // Display the title of each


post

))}

</ul>

)}

</div>

);

export default Posts;

Key Points in this Example:

 useEffect: Used to fetch data when the component mounts.

 setPosts: Updates the state with the fetched posts.

 setLoading: Controls the loading state to show a "Loading..."


message while the data is being fetched.

 fetch: Makes an HTTP request to fetch data from an API.


Sure! Here’s a much simpler example of using useContext to share a value
(like a simple "counter") across components in React.

Example: Simple Counter with useContext

Step 1: Create the Context

We’ll first create a context to share the counter state.

import React, { createContext, useState } from 'react';

// Create a context to manage the counter value

const CounterContext = createContext();

// Create a provider component that will wrap the app

export function CounterProvider({ children }) {

const [counter, setCounter] = useState(0); // Initial counter value

const increment = () => {

setCounter(counter + 1); // Increment the counter

};

const decrement = () => {

setCounter(counter - 1); // Decrement the counter

};

return (

<CounterContext.Provider value={{ counter, increment,


decrement }}>

{children}

</CounterContext.Provider>

);

}
export default CounterContext;

Step 2: Consume the Context in a Component

Now, let’s use useContext in a component to read and update the counter
state.

import React, { useContext } from 'react';

import { CounterContext } from './CounterContext'; // Import the context

function Counter() {

const { counter, increment, decrement } = useContext(CounterContext);


// Get the context values

return (

<div>

<h2>Counter: {counter}</h2>

<button onClick={increment}>Increment</button>

<button onClick={decrement}>Decrement</button>

</div>

);

export default Counter;

Step 3: Use the CounterProvider in Your App

Finally, we’ll wrap the entire app in the CounterProvider to give access to
the context.

import React from 'react';

import { CounterProvider } from './CounterContext'; // Import the provider

import Counter from './Counter'; // Import the Counter component

function App() {
return (

<CounterProvider>

<Counter />

</CounterProvider>

);

export default App;

Explanation:

1. CounterContext: This is where we create the context that will


manage the counter state.

2. useState: We use useState to initialize and manage the counter


value.

3. useContext: In the Counter component, we use useContext to


access the shared counter value and the increment and decrement
functions.

4. CounterProvider: This wraps the app and provides the context to all
components inside it, so they can access the counter state.

How it works:

 When you click the Increment button, the counter increases by 1.

 When you click the Decrement button, the counter decreases by 1.

 The CounterContext allows the counter value to be shared between


components, and useContext lets us access and update that value
easily.

5.7 Event Handling in React

In React, handling events is similar to handling events in traditional


JavaScript, but there are some key differences. React has its own synthetic
event system, which is a cross-browser wrapper around the browser's
native events. This system works similarly to the DOM events but has the
advantage of being normalized.

Here's a breakdown of event handling in React:

1. Basic Event Handling in React


In React, you can add event listeners using the camelCase syntax (e.g.,
onClick, onChange, onSubmit) instead of the lowercase syntax used in
plain HTML.

Example: Simple Button Click Event

import React, { useState } from 'react';

function App() {

const [message, setMessage] = useState('Hello World');

// Event handler function

const handleClick = () => {

setMessage('Button was clicked!');

};

return (

<div>

<h1>{message}</h1>

<button onClick={handleClick}>Click Me</button>

</div>

);

export default App;

Explanation:

 onClick: The onClick event is used to trigger the handleClick


function when the button is clicked.

 useState: We use useState to manage the state (message) and


update it when the button is clicked.

 Event Handler: The handleClick function updates the message


when the button is clicked.

2. Event Handlers with Parameters


Sometimes, you might want to pass arguments to the event handler
function.

Example: Passing Arguments to Event Handler

import React from 'react';

function App() {

const handleClick = (name) => {

alert(`Hello, ${name}!`);

};

return (

<div>

<button onClick={() => handleClick('Alice')}>Say Hello to


Alice</button>

<button onClick={() => handleClick('Bob')}>Say Hello to


Bob</button>

</div>

);

export default App;

Explanation:

 The handleClick function accepts a name argument, and we use an


arrow function inside the onClick event to pass the argument when
calling handleClick.

Key Concepts of Event Handling in React:

1. Synthetic Events: React uses a synthetic event system that wraps


the browser’s native events.

2. CamelCase Naming: In React, event names are written in


camelCase, like onClick, onChange, etc.
3. Event Binding: In class components, event handlers need to be
explicitly bound to the component instance. This is not necessary in
functional components.

4. Handling State: In event handlers, we can update the component


state using useState (in functional components) or this.setState (in
class components).

5. Form Events: Common form events include onChange, onSubmit,


and onInput.

5.8 Forms – Controlled Components, Submission, and Validation in


React

In React, forms can be handled using controlled components. A controlled


component is an input element whose value is controlled by the state in
React. React takes care of keeping the form fields in sync with the
component state, making it easier to handle form submissions and
validations.

Key Concepts:

 Controlled Components: Form elements whose values are


controlled by the component’s state.

 Uncontrolled Components: Form elements that manage their own


state, and React does not manage the input state.

 Form Validation: Ensuring the data entered into a form is valid


before submission.

1. Controlled Components

A controlled component is an input field whose value is controlled by


React's state. This allows React to manage the state of form fields, making
it easier to handle form submissions and validations.

Example: Controlled Input Field

import React, { useState } from 'react';

function App() {

const [name, setName] = useState('');

// Handle input change

const handleChange = (event) => {


setName(event.target.value);

};

// Handle form submission

const handleSubmit = (event) => {

event.preventDefault();

alert('Form submitted with name: ' + name);

};

return (

<form onSubmit={handleSubmit}>

<input

type="text"

value={name} // Controlled by React state

onChange={handleChange} // Update state on input change

placeholder="Enter your name"

/>

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

</form>

);

export default App;

Explanation:

 value={name}: The input's value is bound to the name state,


making it a controlled component.

 onChange={handleChange}: Updates the state whenever the


user types in the input field.

 handleSubmit: Handles the form submission, preventing the


default behavior and showing the submitted value.
2. Form Submission

In React, when handling form submissions, you typically prevent the


default form submission behavior using event.preventDefault(). This
allows you to handle the form submission manually and update the state
or perform any other actions you need.

Example: Form Submission Handling

import React, { useState } from 'react';

function App() {

const [email, setEmail] = useState('');

const [password, setPassword] = useState('');

const handleEmailChange = (event) => setEmail(event.target.value);

const handlePasswordChange = (event) =>


setPassword(event.target.value);

const handleSubmit = (event) => {

event.preventDefault();

// Form submission logic here

alert(`Submitted: Email - ${email}, Password - ${password}`);

};

return (

<form onSubmit={handleSubmit}>

<input

type="email"

value={email}

onChange={handleEmailChange}

placeholder="Enter your email"

/>
<input

type="password"

value={password}

onChange={handlePasswordChange}

placeholder="Enter your password"

/>

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

</form>

);

export default App;

Explanation:

 onSubmit={handleSubmit}: The form submission is controlled by


React.

 event.preventDefault(): Prevents the default form submission


action (which would reload the page), allowing us to handle it in
React.

3. Form Validation

Form validation is important to ensure that the user enters the correct
data before submitting the form. React provides a way to validate input
fields by checking the values in state before submitting the form.

Example: Form with Validation

import React, { useState } from 'react';

function App() {

const [email, setEmail] = useState('');

const [password, setPassword] = useState('');

const [error, setError] = useState('');

const handleEmailChange = (event) => setEmail(event.target.value);


const handlePasswordChange = (event) =>
setPassword(event.target.value);

const handleSubmit = (event) => {

event.preventDefault();

// Basic validation

if (!email || !password) {

setError('Both fields are required');

} else {

setError('');

alert(`Form submitted: Email - ${email}, Password - ${password}`);

};

return (

<div>

<form onSubmit={handleSubmit}>

<input

type="email"

value={email}

onChange={handleEmailChange}

placeholder="Enter your email"

/>

<input

type="password"

value={password}

onChange={handlePasswordChange}

placeholder="Enter your password"


/>

{error && <p style={{ color: 'red' }}>{error}</p>}

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

</form>

</div>

);

export default App;

Explanation:

 Validation Logic: Before submitting the form, we check if both the


email and password are entered. If not, we show an error message.

 Error Handling: The error message is conditionally rendered if


there is an error in the form.

Summary

1. Controlled Components: In React, controlled components have


their values tied to state. This makes it easy to manage form inputs
and ensure that React always has control over the data.

2. Form Submission: You handle form submission using onSubmit


and prevent the default browser behavior using
event.preventDefault().

5.9 Conditional Rendering in React – if, Ternary, &&

Conditional rendering in React allows you to render different UI elements


or components based on certain conditions. It can be done using several
approaches:

1. if Statements: Using traditional if conditions to control rendering.

2. Ternary Operator (? :): A compact way to render components or


elements based on a condition.

3. Logical AND (&&): A simple way to render something only if a


condition is true.

Let's look at examples for each of these methods.


1. Using if Statements for Conditional Rendering

In React, you can use the if statement to conditionally render parts of the
component. However, you can't directly use if statements inside the JSX;
you need to handle the condition before the return statement.

Example: if Statement

import React, { useState } from 'react';

function App() {

const [isLoggedIn, setIsLoggedIn] = useState(false);

let content;

if (isLoggedIn) {

content = <h1>Welcome Back!</h1>;

} else {

content = <h1>Please log in</h1>;

return (

<div>

{content}

<button onClick={() => setIsLoggedIn(!isLoggedIn)}>

{isLoggedIn ? 'Log Out' : 'Log In'}

</button>

</div>

);

export default App;

Explanation:
 if Statement: We use an if statement to check whether the user is
logged in (isLoggedIn). Based on that, we set the content variable to
display the appropriate message.

 Toggling State: The button toggles between "Log In" and "Log Out"
based on the isLoggedIn state.

2. Using the Ternary Operator for Conditional Rendering

The ternary operator is a more concise way to write conditional logic in


React. It has the following syntax:

condition ? expression_if_true : expression_if_false;

Example: Ternary Operator

import React, { useState } from 'react';

function App() {

const [isLoggedIn, setIsLoggedIn] = useState(false);

return (

<div>

{isLoggedIn ? <h1>Welcome Back!</h1> : <h1>Please log in</h1>}

<button onClick={() => setIsLoggedIn(!isLoggedIn)}>

{isLoggedIn ? 'Log Out' : 'Log In'}

</button>

</div>

);

export default App;

Explanation:

 Ternary Operator: We use the ternary operator to display either


"Welcome Back!" or "Please log in" based on the isLoggedIn state.

 Toggling State: The button toggles between "Log In" and "Log Out"
based on the isLoggedIn state.
3. Using Logical AND (&&) for Conditional Rendering

The logical AND (&&) operator can also be used for conditional rendering.
It's commonly used when you want to render something only if a condition
is true.

Example: Logical AND (&&) Operator

import React, { useState } from 'react';

function App() {

const [isLoggedIn, setIsLoggedIn] = useState(false);

return (

<div>

{isLoggedIn && <h1>Welcome Back!</h1>} {/* Renders only if


isLoggedIn is true */}

<button onClick={() => setIsLoggedIn(!isLoggedIn)}>

{isLoggedIn ? 'Log Out' : 'Log In'}

</button>

</div>

);

export default App;

Explanation:

 && Operator: The text "Welcome Back!" is only rendered if


isLoggedIn is true. If it's false, nothing is rendered in its place.

 Toggling State: The button toggles between "Log In" and "Log Out"
based on the isLoggedIn state.

Summary of Conditional Rendering Methods:

1. if Statement: Used when you need to perform more complex


conditions or multiple lines of logic before rendering JSX.

o Best for multi-line logic before the JSX.


2. Ternary Operator (? :): A compact form of if-else logic for inline
conditional rendering.

o Best for simple two-way conditions (if/else).

3. Logical AND (&&): Renders a component only if a condition is true,


otherwise renders nothing.

o Best for rendering something conditionally without


needing an "else" case.

5.10 Lists and Keys in React

In React, rendering lists of elements is a common operation. To efficiently


update and manage lists, React requires a key for each item in the list.
The key helps React identify which items have changed, been added, or
removed, making the update process more efficient.

Rendering Lists in React

In React, we use the map() function to render lists of elements. The map()
function iterates over an array and returns a new array of elements that
can be rendered in JSX.

Example: Rendering a List without Keys

import React from 'react';

function App() {

const fruits = ['Apple', 'Banana', 'Orange', 'Mango'];

return (

<div>

<h1>Fruits List</h1>

<ul>

{fruits.map(fruit => (

<li>{fruit}</li> // No key here

))}

</ul>
</div>

);

export default App;

Why We Need Keys

When rendering lists in React, keys help React efficiently update and
render the correct components when the list changes. Without keys, React
would have to re-render all the list items, which can negatively affect
performance, especially for large lists.

Keys need to be:

 Unique: Each element in the list must have a unique key.

 Stable: The key should not change between renders.

 Consistent: It should uniquely identify an element across the list.

Importance of Keys

1. Efficient Re-rendering: React uses keys to optimize rendering and


to determine which elements need to be updated. Without keys,
React would have to compare all items in the list, which can be
inefficient.

2. Tracking Elements: Keys help React track individual elements in


the list. This helps React understand which items have been
modified, added, or removed, so it can efficiently re-render only the
affected parts.

3. Optimized DOM Updates: With keys, React can perform minimal


DOM manipulations, ensuring better performance, especially with
large lists or dynamic data.

Rendering Lists with Keys

To add keys to the elements in the list, you pass the key prop to each
element in the list. The key should be a unique identifier for each item.

Example: Rendering a List with Keys

import React from 'react';


function App() {

const fruits = ['Apple', 'Banana', 'Orange', 'Mango'];

return (

<div>

<h1>Fruits List</h1>

<ul>

{fruits.map((fruit, index) => (

<li key={index}>{fruit}</li> // Each item has a unique key

))}

</ul>

</div>

);

export default App;

Explanation:

 The key={index} is used to assign a unique identifier to each list


item. In this case, we're using the index of the item in the array as
the key. However, using the index as the key is not recommended if
the order of items might change, as it can lead to issues when React
compares the keys.

When to Use Keys

 When you are rendering a list of elements dynamically.

 When the list is dynamic and items can be added, removed, or


reordered.

 When you need efficient updates to the list when the data
changes.

Best Practices for Keys


1. Use a Unique ID: The best practice is to use a unique ID from
your data (e.g., an ID from a database or a generated UUID). This is
more reliable than using array indices, especially when items are
removed or reordered.

Example:

import React from 'react';

function App() {

const fruits = [

{ id: 1, name: 'Apple' },

{ id: 2, name: 'Banana' },

{ id: 3, name: 'Orange' },

{ id: 4, name: 'Mango' }

];

return (

<div>

<h1>Fruits List</h1>

<ul>

{fruits.map(fruit => (

<li key={fruit.id}>{fruit.name}</li> // Use unique ID as key

))}

</ul>

</div>

);

export default App;

Why this is better:


o Using a unique id as the key ensures that each item is
uniquely identified and remains stable across renders, even if
the list changes (items are added, removed, or reordered).

2. Avoid Using Array Index as Key: If the list changes (e.g., items
are added or removed), using the index as the key can cause
rendering bugs because the index does not uniquely represent the
item if the list is modified. This can lead to incorrect state being
retained between renders.

Example of why it's not recommended:

// This can cause issues when list items are reordered

<li key={index}>{fruit.name}</li>

How Keys Help in List Updates

Consider the following example, where a fruit is removed from the list:

import React, { useState } from 'react';

function App() {

const [fruits, setFruits] = useState([

{ id: 1, name: 'Apple' },

{ id: 2, name: 'Banana' },

{ id: 3, name: 'Orange' },

{ id: 4, name: 'Mango' }

]);

const removeFruit = (id) => {

setFruits(fruits.filter(fruit => fruit.id !== id));

};

return (

<div>

<h1>Fruits List</h1>

<ul>
{fruits.map(fruit => (

<li key={fruit.id}>

{fruit.name}

<button onClick={() => removeFruit(fruit.id)}>Remove</button>

</li>

))}

</ul>

</div>

);

export default App;

Explanation:

 Removing an Item: When you remove a fruit from the list, React
uses the key to track the items. React efficiently updates the list
without having to re-render the entire list, only removing the correct
item.

Summary

 Keys are essential for React to manage list elements efficiently and
perform minimal DOM updates.

 Unique Keys should be used for each element in a list (e.g.,


database IDs or unique values).

 Avoid using array indices as keys unless you are sure the list won't
change in terms of order.

 Using keys improves performance and ensures that React can


efficiently update the DOM when the list changes.

Let me know if you need further clarification or examples!

5.11 Styling in React – CSS, CSS Modules, CSS-in-JS

Styling is a crucial aspect of any web application, and in React, there are
several ways to style components. The most common approaches include
CSS, CSS Modules, and CSS-in-JS.
Let's dive into each of these styling approaches in React:

1. CSS (Traditional CSS)

In traditional CSS, you create global stylesheets and link them to your
React components. The styles are applied globally across the application,
so they can affect all components unless scoped specifically.

Example of Global CSS Styling:

// App.css

.button {

background-color: blue;

color: white;

padding: 10px;

border-radius: 5px;

// App.js

import React from 'react';

import './App.css'; // Importing the CSS file

function App() {

return (

<div>

<button className="button">Click Me</button>

</div>

);

export default App;

Advantages of Global CSS:

 Simple and easy to use.

 Well-known approach for most web developers.


Disadvantages of Global CSS:

 Global namespace: It can lead to style conflicts, as all styles are


globally scoped.

 Harder to maintain: As your app grows, managing large CSS files


can become difficult.

2. CSS Modules

CSS Modules allow you to scope your CSS to the specific component. Each
component gets a unique class name, ensuring that the styles do not
conflict with other components.

Example of CSS Modules:

1. Create a CSS Module:


You create a CSS file with a .module.css extension.

/* Button.module.css */

.button {

background-color: green;

color: white;

padding: 10px;

border-radius: 5px;

2. Import and Use the CSS Module:


In the React component, you import the CSS module and apply the
styles using the imported object.

// Button.js

import React from 'react';

import styles from './Button.module.css'; // Import CSS module

function Button() {

return (

<button className={styles.button}>Click Me</button> {/* Use class


name from module */}

);
}

export default Button;

Advantages of CSS Modules:

 Scoped styles: Styles are scoped to the component, avoiding


conflicts.

 Automatic class name hashing: React automatically generates


unique class names.

 Easier to maintain: Styles are scoped to components, making it


easier to understand and modify.

Disadvantages of CSS Modules:

 It requires the CSS to be modularized, so you can't use global CSS


easily unless you use global selectors within the module.

 Limited flexibility when applying certain styles globally.

3. CSS-in-JS

CSS-in-JS allows you to write CSS directly inside your JavaScript files, and
the styles are scoped to components. This approach is useful when you
need dynamic styling or want to style components conditionally.

There are several popular libraries for CSS-in-JS, like styled-


components, emotion, and JSS. Here's an example using styled-
components.

Example of CSS-in-JS using styled-components:

First, install the styled-components library:

npm install styled-components

Then, you can write your CSS inside your JavaScript using tagged
template literals.

// App.js

import React from 'react';

import styled from 'styled-components'; // Import styled-components


library

// Create a styled button component


const Button = styled.button`

background-color: orange;

color: white;

padding: 10px;

border-radius: 5px;

&:hover {

background-color: darkorange;

`;

function App() {

return (

<div>

<Button className={{backgroundColor:”blue”}}>Click
Me</Button> {/* Styled button */}

</div>

);

export default App;

Advantages of CSS-in-JS:

 Dynamic styling: You can pass props to style components


conditionally based on component state or other logic.

 Scoped styling: Styles are scoped to the component, so you don't


have to worry about class name conflicts.

 JavaScript-powered: Styles can be directly integrated with


JavaScript, making it easy to handle dynamic themes and
transitions.

Disadvantages of CSS-in-JS:
 Performance: It might affect performance due to runtime style
generation, especially if the styles are very dynamic.

 Increased Bundle Size: Because the CSS is included in JavaScript


files, it can increase the size of the JavaScript bundle.

 Learning Curve: You may need to learn a new library like styled-
components or emotion.

Comparison of Approaches

CSS CSS-in-JS (styled-


Feature CSS Modules
(Traditional) components)

Scope of Component-
Global Component-level
Styles level

Ease of Use Easy Moderate Moderate

Dynamic Not possible Possible with Highly possible (conditional


Styling directly inline styles styling with props)

Class Name
Possible No collision No collision
Collision

Depends on
Performance Efficient Can be affected by runtime
size of CSS

Easy to maintain, but


Can be hard as Easy to
Maintenance requires understanding
app grows maintain
CSS-in-JS libraries

Conclusion

 Traditional CSS is the simplest approach but may lead to issues


with global namespace and maintainability.

 CSS Modules are great for scoping styles to components and


avoiding style conflicts.

 CSS-in-JS is the most flexible approach, enabling dynamic styling


and scoped styles directly within your JavaScript code.

Choosing between these approaches depends on the complexity of your


project and your team's preferences. For small projects, traditional CSS or
CSS Modules might be sufficient, but for larger, more dynamic
applications, CSS-in-JS can offer powerful features.

Let me know if you'd like any further details!


5.12 React Router – Setup, Routes, Parameters

React Router is a standard library used for routing in React applications. It


enables navigation between views (components) and allows for a
seamless, single-page application (SPA) experience.

React Router Setup:

1. Install React Router: First, install react-router-dom in your React


project.

bash

CopyEdit

npm install react-router-dom

2. Basic Setup:

Import the necessary components from react-router-dom to define routes


and navigation.

// App.js

import React from 'react';

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

// Components

function Home() {

return <h2>Home Page</h2>;

function About() {

return <h2>About Page</h2>;

function User({ match }) {

return <h2>User ID: {match.params.userId}</h2>;

}
function App() {

return (

<Router>

<nav>

<Link to="/">Home</Link> |

<Link to="/about">About</Link> |

<Link to="/user/1">User 1</Link>

</nav>

{/* Directly render routes without using Switch */}

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

<Route path="/about" component={About} />

<Route path="/user/:userId" component={User} />

</Router>

);

export default App;

2. Async/Await – Fetching Data

Example using async/await to fetch data from an API:

import React, { useState, useEffect } from 'react';

function App() {

const [data, setData] = useState([]);

const [loading, setLoading] = useState(true);

useEffect(() => {

async function fetchData() {


try {

const response = await


fetch("https://jsonplaceholder.typicode.com/posts");

const data = await response.json();

setData(data);

setLoading(false);

} catch (error) {

console.error("Error fetching data:", error);

setLoading(false);

fetchData();

}, []);

if (loading) return <p>Loading...</p>;

return (

<div>

<h1>Posts</h1>

<ul>

{data.map(post => (

<li key={post.id}>{post.title}</li>

))}

</ul>

</div>

);

export default App;

3. Error Handling

Handling errors with try/catch block in async code:

import React, { useState, useEffect } from 'react';


function App() {

const [data, setData] = useState([]);

const [error, setError] = useState(null);

useEffect(() => {

async function fetchData() {

try {

const response = await


fetch("https://jsonplaceholder.typicode.com/posts");

if (!response.ok) {

throw new Error("Network response was not ok");

const data = await response.json();

setData(data);

} catch (error) {

setError(error.message);

fetchData();

}, []);

if (error) return <p>Error: {error}</p>;

return (

<div>

<h1>Posts</h1>

<ul>

{data.map(post => (
<li key={post.id}>{post.title}</li>

))}

</ul>

</div>

);

export default App;

4. React Performance Optimization

React.memo

Prevent unnecessary re-renders of components using React.memo:

import React, { useState } from 'react';

const Counter = React.memo(({ count }) => {

console.log('Rendering Counter component');

return <h2>Count: {count}</h2>;

});

function App() {

const [count, setCount] = useState(0);

return (

<div>

<button onClick={() => setCount(count + 1)}>Increment</button>

<Counter count={count} />

</div>

);

}
export default App;

React.lazy for Code Splitting

Lazy load a component to reduce the bundle size and improve


performance:

import React, { Suspense, lazy } from 'react';

const LazyComponent = lazy(() => import('./LazyComponent'));

function App() {

return (

<div>

<Suspense fallback={<div>Loading...</div>}>

<LazyComponent />

</Suspense>

</div>

);

export default App;

In the above example, LazyComponent will only be loaded when it’s


needed, which helps improve initial load time.

Summary:

1. React Router: Used to manage navigation in your app.

2. Async/Await: Makes it easier to fetch data from an API in React


using async functions.

3. Error Handling: Use try/catch blocks to catch and handle errors in


async functions.

4. Optimization: Use React.memo to prevent unnecessary re-


renders and React.lazy for code splitting to improve performance.

You might also like