0% found this document useful (0 votes)
23 views81 pages

React FullStack

React.js is a widely-used JavaScript library for building interactive user interfaces, emphasizing a component-based architecture for efficient and maintainable development. Key features include the Virtual DOM for performance optimization, JSX for readable code, and Hooks for managing state and side effects in functional components. Setting up a React project can be done easily through methods like Create React App or Vite, with extensive resources available for learning and development.

Uploaded by

Sai krishna
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views81 pages

React FullStack

React.js is a widely-used JavaScript library for building interactive user interfaces, emphasizing a component-based architecture for efficient and maintainable development. Key features include the Virtual DOM for performance optimization, JSX for readable code, and Hooks for managing state and side effects in functional components. Setting up a React project can be done easily through methods like Create React App or Vite, with extensive resources available for learning and development.

Uploaded by

Sai krishna
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 81

Introduction to React.

js

React.js is a popular JavaScript library used for building interactive user interfaces, especially for
single-page applications. Developed by Facebook, it follows a component-based architecture that
makes UI development more efficient and maintainable. React allows developers to create
reusable UI components and efficiently update and render only the necessary parts of a web
page, leading to better performance.

Key Features of React.js

1. Component-Based Architecture
React applications are built using reusable components, making the code more modular
and maintainable. Each component represents a part of the UI and can have its own logic
and state.
2. Virtual DOM
React uses a Virtual DOM to improve performance. Instead of directly manipulating the
actual DOM, it updates a lightweight copy (Virtual DOM), compares changes, and
updates only the affected elements.
3. JSX (JavaScript XML)
JSX is a syntax extension for JavaScript that allows developers to write HTML-like code
inside JavaScript. It makes the UI code more readable and easier to write.
4. State and Props
o State: A component’s internal data storage, allowing it to manage dynamic
content.
o Props: Short for properties, props allow data to be passed between
components, making them reusable and dynamic.
5. One-Way Data Binding
React follows a unidirectional data flow, ensuring better control over data and making
debugging easier.
6. Hooks
React Hooks (like useState, useEffect) allow functional components to manage state
and side effects without needing class components.
7. React Router
For navigation, React Router enables seamless client-side routing, allowing users to
switch between different views without reloading the page.
8. Strong Community Support
React has a vast ecosystem with numerous third-party libraries, tools, and strong
community support, making it easier for developers to build scalable applications.

Basic Example of React Component


import React from "react";

function Greeting() {
return <h1>Hello, Welcome to React!</h1>;
}
export default Greeting;

Conclusion

React.js is widely used for building modern web applications due to its efficiency, reusability,
and scalability. With features like the Virtual DOM, component-based structure, and hooks, it
simplifies UI development. Whether you are a beginner or an experienced developer, learning
React can be a valuable skill for front-end development.

Setting Up React.js and Useful Resources

Setting up a React.js project is straightforward, and there are multiple ways to get started. Below
is a step-by-step guide to setting up a React environment, along with useful resources for
learning React.

1. Setting Up React.js
Method 1: Using Create React App (CRA) [Recommended for Beginners]

Create React App (CRA) is the easiest way to set up a new React project with a good default
configuration.

Steps to Install:

1. Install Node.js and npm


o Download and install Node.js (it includes npm).
o Verify installation using:
o node -v
o npm -v
2. Create a React App
Open a terminal and run:
3. npx create-react-app my-app
4. cd my-app
5. npm start
o npx runs the latest package without installing it globally.
o my-app is the project name (change it as needed).
6. Start the Development Server
Once inside the project directory, start the app using:
7. npm start

This launches a development server at http://localhost:3000/.

Method 2: Using Vite (Faster Alternative to CRA)

Vite is a modern build tool that provides a faster and lighter development experience.
Steps to Install:

1. Run the following command:


2. npm create vite@latest my-app --template react
3. cd my-app
4. npm install
5. npm run dev
6. Visit http://localhost:5173/ in the browser.

Method 3: Adding React to an Existing HTML File (CDN Method)

If you want to use React without setting up a full project, you can use a CDN.

Example:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React with CDN</title>
</head>
<body>
<div id="root"></div>

<script
src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-
dom.development.js"></script>
<script>
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(React.createElement('h1', {}, 'Hello, React!'));
</script>
</body>
</html>

This method is useful for small-scale applications or learning React basics.

2. Useful Resources to Learn React.js


Official Documentation

• React Official Docs: https://react.dev/

Online Courses

• ReactJS - The Complete Guide (Udemy)


• Frontend Masters - React
• freeCodeCamp React Course (YouTube)
Interactive Learning Platforms

• Scrimba: https://scrimba.com/learn/learnreact
• Codecademy React Course: https://www.codecademy.com/learn/react-101

Books

• "Learning React" by Alex Banks & Eve Porcello


• "React Up & Running" by Stoyan Stefanov

3. React Development Tools


Code Editor

• VS Code (Recommended) – Download


• Extensions:
o ES7+ React/Redux Snippets
o React Developer Tools

React Developer Tools

• Install React Developer Tools extension for Chrome/Firefox to inspect React


components.

Conclusion

Setting up React is simple, and there are multiple ways to get started depending on your needs.
Create React App and Vite are the best options for beginners, while CDN is good for quick
testing. With plenty of online resources, documentation, and community support, learning React
has never been easier.

React App Component and JSX

React applications are built using components, which are reusable and independent pieces of UI.
Components use JSX (JavaScript XML) to describe the UI structure in a syntax that resembles
HTML. JSX makes it easier to write and visualize component structures within JavaScript.

1. React Components

A component in React is a JavaScript function or class that returns JSX to render UI elements.
React supports two types of components:
a) Functional Components (Recommended)

Functional components are simpler and primarily use React Hooks for state and lifecycle
management.

Example: Functional Component

import React from "react";

function Greeting() {
return <h1>Hello, Welcome to React!</h1>;
}

export default Greeting;


b) Class Components (Older Approach)

Class components were used before React Hooks. They include a render() method to return
JSX.

Example: Class Component

import React, { Component } from "react";

class Greeting extends Component {


render() {
return <h1>Hello, Welcome to React!</h1>;
}
}

export default Greeting;

2. JSX (JavaScript XML)

JSX is a syntax extension that allows writing HTML-like code inside JavaScript. React uses JSX
to create UI components more efficiently. JSX elements must follow JavaScript rules, such as
using curly braces {} for expressions.

a) Writing JSX

Example of JSX inside a Component:

import React from "react";

function App() {
const userName = "John";
return <h1>Hello, {userName}!</h1>;
}
export default App;

• JSX allows embedding JavaScript expressions using {}.


• In the example, {userName} dynamically inserts the value "John" into the output.

b) JSX Rules

• JSX elements must have a single parent element (wrap multiple elements in a
<div> or <> fragment).
• Class attributes in JSX should be written as className (not class).
• Inline styles should use an object with camelCase properties.

Example: JSX Rules

function App() {
return (
<div>
<h1 className="heading">Hello, React!</h1>
<p style={{ color: "blue", fontSize: "20px" }}>This is a paragraph.</p>
</div>
);
}

export default App;

3. Combining Components in a React App

A React app is built by combining multiple components.

Example: Parent and Child Components

import React from "react";


import Greeting from "./Greeting"; // Importing Child Component

function App() {
return (
<div>
<Greeting />
<p>This is a React app with multiple components.</p>
</div>
);
}

export default App;

Here, Greeting is a separate component, imported and used inside the App component.
Conclusion

React components make UI development modular and reusable, while JSX simplifies writing
HTML-like structures inside JavaScript. Functional components are the preferred approach due
to their simplicity and compatibility with Hooks. Understanding components and JSX is the
foundation of building React applications.

Functional Components in React

Functional components are the most commonly used type of component in React. They are
simple JavaScript functions that return JSX (React's syntax for UI rendering). Unlike class
components, functional components are lighter, easier to read, and perform better because
they do not rely on complex lifecycle methods.

1. What is a Functional Component?

A functional component is simply a JavaScript function that:

• Takes props as input (optional)


• Returns JSX (the UI structure)

Example: A Simple Functional Component

import React from "react";

function Greeting() {
return <h1>Hello, Welcome to React!</h1>;
}

export default Greeting;

• This component renders an <h1> tag with a message.


• It does not use a class or lifecycle methods.

2. Functional Components with Props

Props (short for properties) allow passing data from a parent component to a child component.

Example: Functional Component with Props

import React from "react";


function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}

export default Greeting;

• {props.name} dynamically inserts the name passed from the parent.

Using the Component in App.js

import React from "react";


import Greeting from "./Greeting";

function App() {
return <Greeting name="John" />;
}

export default App;

• The Greeting component receives "John" as a prop and displays "Hello, John!"

3. Functional Components with State (Using Hooks)

By default, functional components do not have state. However, React Hooks (like useState)
allow functional components to manage state.

Example: Functional Component with State (useState Hook)

import React, { useState } from "react";

function Counter() {
const [count, setCount] = useState(0); // Declaring state

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

export default Counter;

• useState(0) initializes count with 0.


• Clicking the button updates the count value.
4. Functional Components with Side Effects (useEffect Hook)

The useEffect hook allows functional components to perform side effects like data fetching,
event listeners, or API calls.

Example: Fetching Data in a Functional Component

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

function DataFetcher() {
const [data, setData] = useState([]);

useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((json) => setData(json));
}, []);

return (
<div>
<h2>Posts</h2>
<ul>
{data.slice(0, 5).map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}

export default DataFetcher;

• useEffect(() => {}, []) runs the API call once when the component mounts.
• The component fetches and displays posts dynamically.

5. Why Use Functional Components?

1. Simpler and More Readable – No need for this or lifecycle methods.


2. Better Performance – Functional components are optimized and execute faster.
3. Hooks Support – Functional components use useState, useEffect, etc. for state
and side effects.
4. Less Boilerplate Code – No need for constructor or render().
5. Encouraged by React Team – React now favors functional components over class
components.
Conclusion

Functional components are the foundation of modern React development. They are simple
functions that return JSX and can use Hooks (useState, useEffect) to manage state and side
effects. Due to their efficiency, they have replaced class components in most React applications.

CSS Styles in React.js

Styling is an essential part of building React applications. React provides multiple ways to apply
CSS styles, from traditional CSS files to modern techniques like CSS modules and styled-
components.

1. Applying CSS in React

There are several ways to style React components:

1. Using External CSS Files (Traditional Approach)


2. Inline CSS (Using Style Attribute)
3. CSS Modules (Scoped Styles)
4. Styled Components (CSS-in-JS Approach)

2. Using External CSS Files

You can create a separate .css file and import it into your React component.

Example: External CSS File

1. Create a CSS file (styles.css):

.container {
text-align: center;
background-color: lightblue;
padding: 20px;
border-radius: 10px;
}

2. Import and Use in a React Component (App.js):

import React from "react";


import "./styles.css"; // Importing external CSS
function App() {
return (
<div className="container">
<h1>Styled with External CSS</h1>
</div>
);
}

export default App;

• This method works like regular CSS but applies styles globally.

3. Inline CSS (Using Style Attribute)

React allows inline styling using an object with camelCase properties.

Example: Inline CSS in JSX


import React from "react";

function InlineStyle() {
const headingStyle = {
color: "red",
fontSize: "24px",
textAlign: "center",
backgroundColor: "yellow",
};

return <h1 style={headingStyle}>Styled with Inline CSS</h1>;


}

export default InlineStyle;

• Styles are written as a JavaScript object.


• Properties use camelCase (e.g., backgroundColor instead of background-color).

4. CSS Modules (Scoped Styles)

CSS Modules allow you to scope styles to a specific component, preventing conflicts.

Example: Using CSS Modules

1. Create a CSS Module file (styles.module.css):

.title {
color: green;
font-size: 28px;
text-align: center;
}

2. Import and Use in a React Component (App.js):

import React from "react";


import styles from "./styles.module.css"; // Import CSS module

function App() {
return <h1 className={styles.title}>Styled with CSS Modules</h1>;
}

export default App;

• Styles are applied only to this component, avoiding global conflicts.

5. Styled Components (CSS-in-JS)

Styled-components allow defining styles directly inside JavaScript using template literals.

Example: Using Styled Components

1. Install styled-components:

npm install styled-components

2. Use styled-components in a React component:

import React from "react";


import styled from "styled-components";

const Title = styled.h1`


color: white;
background-color: purple;
padding: 10px;
text-align: center;
border-radius: 5px;
`;

function App() {
return <Title>Styled with Styled-Components</Title>;
}

export default App;

• The styled.h1 function creates a styled <h1> tag.


• Styled-components support dynamic styling using props.

Conclusion

React provides multiple ways to style components. External CSS files are simple and widely
used, while inline styles are useful for quick styling. CSS Modules ensure scoped styles, and
styled-components enable modern CSS-in-JS styling. Choosing the right method depends on the
project's needs.

Handling Click Events in React

Click events in React are handled using event listeners. React follows the synthetic event system,
meaning events work consistently across different browsers.

1. Adding Click Events

React uses the onClick event to detect button clicks. The event is attached to an element using
JSX syntax.

Example: Basic Click Event


import React from "react";

function ClickHandler() {
const handleClick = () => {
alert("Button clicked!");
};

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


}

export default ClickHandler;

• Here, handleClick is a function triggered when the button is clicked.


• React uses camelCase (onClick) instead of lowercase (onclick).

2. Click Event with Parameters

To pass arguments in an event handler, use an arrow function inside onClick.


Example: Passing Parameters in Click Event
import React from "react";

function ClickHandler() {
const showMessage = (name) => {
alert(`Hello, ${name}!`);
};

return <button onClick={() => showMessage("John")}>Click Me</button>;


}

export default ClickHandler;

• The arrow function () => showMessage("John") ensures the function runs only
when clicked.

3. Click Event with State (Updating State on Click)

React components can update state when a button is clicked using the useState hook.

Example: Click to Change State


import React, { useState } from "react";

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

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

export default Counter;

• Clicking the button updates the count state using setCount.

4. Event Object in Click Events

React provides an event object (e) containing event details.

Example: Using Event Object


import React from "react";
function ClickHandler() {
const handleClick = (e) => {
console.log("Event type:", e.type);
};

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


}

export default ClickHandler;

• e.type logs "click" when the button is clicked.

5. Prevent Default Behavior in Click Events

The preventDefault() method prevents the default action of an element, such as stopping a
link from navigating.

Example: Prevent Default on Click


import React from "react";

function PreventDefault() {
const handleClick = (e) => {
e.preventDefault();
alert("Link click prevented!");
};

return <a href="https://example.com" onClick={handleClick}>Click Me</a>;


}

export default PreventDefault;

• Normally, clicking the link would navigate to another page.


• e.preventDefault() stops this behavior.

Conclusion

Handling click events in React is straightforward using onClick. You can pass parameters,
update state, use event objects, and prevent default behavior. Mastering these techniques is
essential for building interactive React applications.
useState Hook in React

The useState hook is a built-in React hook that allows functional components to manage state.
Unlike class components that use this.state, functional components can use useState to store
and update state values efficiently.

1. What is useState?

• useState is a function that returns an array with two values:


1. State variable – Stores the current state value.
2. Setter function – Updates the state value.
• The syntax is:
• const [state, setState] = useState(initialValue);
o state → The current state value.
o setState → A function to update the state.
o initialValue → The default value of the state.

2. Basic Example of useState

This example demonstrates a counter using useState.

import React, { useState } from "react";

function Counter() {
const [count, setCount] = useState(0); // Initial state = 0

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

export default Counter;

• Clicking the button increases count by 1.


• setCount(count + 1) updates the state.
3. Using useState with Strings

The useState hook can manage string values as well.

import React, { useState } from "react";

function Greeting() {
const [name, setName] = useState("Guest");

return (
<div>
<h2>Hello, {name}!</h2>
<button onClick={() => setName("John")}>Change Name</button>
</div>
);
}

export default Greeting;

• Clicking the button changes "Guest" to "John".

4. Using useState with Objects

When managing objects, spread operator (...) is used to update specific properties.

import React, { useState } from "react";

function UserInfo() {
const [user, setUser] = useState({ name: "Alice", age: 25 });

return (
<div>
<h2>Name: {user.name}</h2>
<h2>Age: {user.age}</h2>
<button onClick={() => setUser({ ...user, age: user.age + 1 })}>
Increase Age
</button>
</div>
);
}

export default UserInfo;

• setUser({ ...user, age: user.age + 1 }) keeps name unchanged while


updating age.
5. Using useState with Arrays

Updating arrays requires spreading the previous state to avoid mutation.

import React, { useState } from "react";

function ItemList() {
const [items, setItems] = useState(["Apple", "Banana"]);

return (
<div>
<h2>Items:</h2>
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
<button onClick={() => setItems([...items, "Orange"])}>Add
Item</button>
</div>
);
}

export default ItemList;

• setItems([...items, "Orange"]) adds "Orange" to the list.

6. Functional Updates in useState

If the new state depends on the previous state, use a callback function inside setState().

import React, { useState } from "react";

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

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

export default Counter;

• prevCount => prevCount + 1 ensures the latest state is used.


7. Best Practices for useState

• Use the latest state when updating based on the previous value.
• Avoid directly mutating state objects (use spread operator).
• Use separate state variables for unrelated values.
• Use functional updates for performance optimization.

Conclusion

The useState hook is essential for handling state in functional components. It supports
numbers, strings, objects, and arrays. Using it properly ensures reactivity and efficient updates in
React applications.

Lists and Keys in React


Rendering lists in React is a common task when displaying dynamic data. React efficiently
updates the UI using a key to track changes in a list.

1. Rendering Lists in React

React uses the map() function to iterate over an array and render a list of elements dynamically.

Example: Rendering a List of Items


import React from "react";

function ItemList() {
const items = ["Apple", "Banana", "Orange"];

return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}

export default ItemList;


• The map() function iterates over items and returns <li> elements.
• The key helps React track each item efficiently.

2. Using Keys in Lists

Keys help React identify which items changed, added, or removed, optimizing re-rendering.

Why Are Keys Important?

• Improve performance by minimizing unnecessary re-renders.


• Help React track items efficiently when updating lists.

Example: Using Unique Keys


import React from "react";

function UsersList() {
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" }
];

return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}

export default UsersList;

• Keys should be unique for each item (e.g., user.id).


• Avoid using array index unless items won't change.

3. Dynamic Lists with useState

Lists can be updated dynamically using the useState hook.

Example: Adding Items to a List


import React, { useState } from "react";
function TaskList() {
const [tasks, setTasks] = useState(["Task 1", "Task 2"]);

const addTask = () => {


setTasks([...tasks, `Task ${tasks.length + 1}`]);
};

return (
<div>
<ul>
{tasks.map((task, index) => (
<li key={index}>{task}</li>
))}
</ul>
<button onClick={addTask}>Add Task</button>
</div>
);
}

export default TaskList;

• Clicking "Add Task" updates the list dynamically.


• The setTasks([...tasks, newTask]) updates the state without modifying the
original array.

4. Removing Items from a List

Items can be removed using filter() inside setState().

Example: Deleting an Item from a List


import React, { useState } from "react";

function TaskList() {
const [tasks, setTasks] = useState(["Task 1", "Task 2", "Task 3"]);

const removeTask = (taskToRemove) => {


setTasks(tasks.filter(task => task !== taskToRemove));
};

return (
<div>
<ul>
{tasks.map((task, index) => (
<li key={index}>
{task}
<button onClick={() => removeTask(task)}>Delete</button>
</li>
))}
</ul>
</div>
);
}

export default TaskList;

• Clicking "Delete" removes a task from the list.


• filter() returns a new array excluding the deleted task.

5. Rendering Lists of Components

Lists can also contain components instead of simple <li> elements.

Example: List with a Component


import React from "react";

function User({ name }) {


return <li>{name}</li>;
}

function UserList() {
const users = ["Alice", "Bob", "Charlie"];

return (
<ul>
{users.map((user, index) => (
<User key={index} name={user} />
))}
</ul>
);
}

export default UserList;

• The User component is reused for each item.


• It improves modularity and readability.

Conclusion

Lists in React are managed using map(), and keys help React optimize rendering. Using unique
keys, state for dynamic lists, and filter() for deletions ensures efficient list management.
Props and Prop Drilling in React
Props (short for "properties") are a way to pass data from one component to another in React.
However, when deeply nested components need access to props, prop drilling becomes an issue.

1. What are Props?

Props allow components to receive data from their parent components and make React
components reusable.

Example: Passing Props


import React from "react";

function Greeting(props) {
return <h2>Hello, {props.name}!</h2>;
}

function App() {
return <Greeting name="Alice" />;
}

export default App;

• Greeting component receives name as a prop.


• The App component passes "Alice" as a prop.

Using Destructuring for Props


function Greeting({ name }) {
return <h2>Hello, {name}!</h2>;
}

• Destructuring makes the code cleaner.

2. Passing Multiple Props

Multiple props can be passed to a component.

function UserProfile({ name, age }) {


return (
<div>
<h2>Name: {name}</h2>
<p>Age: {age}</p>
</div>
);
}

function App() {
return <UserProfile name="Bob" age={25} />;
}

• UserProfile receives name and age as props.

3. Prop Drilling Problem

Prop drilling occurs when props need to be passed down through multiple components to reach
a deeply nested child.

Example: Prop Drilling Issue


function App() {
const user = { name: "Charlie" };
return <Parent user={user} />;
}

function Parent({ user }) {


return <Child user={user} />;
}

function Child({ user }) {


return <GrandChild user={user} />;
}

function GrandChild({ user }) {


return <h2>User: {user.name}</h2>;
}

export default App;

• The user prop is passed through Parent → Child → GrandChild, even though only
GrandChild needs it.

4. Solutions to Prop Drilling


1. Context API (Best for Global State)

The Context API allows components to access values without manually passing props through
every level.
Example: Using Context API
import React, { createContext, useContext } from "react";

const UserContext = createContext();

function App() {
const user = { name: "Charlie" };

return (
<UserContext.Provider value={user}>
<Parent />
</UserContext.Provider>
);
}

function Parent() {
return <Child />;
}

function Child() {
return <GrandChild />;
}

function GrandChild() {
const user = useContext(UserContext);
return <h2>User: {user.name}</h2>;
}

export default App;

• createContext() creates a global state.


• UserContext.Provider shares the user data.
• useContext(UserContext) allows GrandChild to access data directly.

2. State Management Libraries (Redux, Zustand, Recoil)

For larger applications, Redux or Zustand manage state globally, avoiding prop drilling.

Conclusion

Props allow data sharing between components, but prop drilling makes it inefficient when data
is needed deep in the component tree. Solutions like Context API and state management
libraries help prevent unnecessary prop passing.
Controlled Form Inputs in React
A controlled component in React is a form element (like an input, textarea, or select) whose
value is controlled by React state. This approach ensures that React handles the input's value and
updates the UI accordingly.

1. What is a Controlled Component?

In a controlled component, the input value is managed using the useState hook. The component
re-renders whenever the state changes.

Example: Controlled Input Field


import React, { useState } from "react";

function ControlledInput() {
const [text, setText] = useState("");

const handleChange = (event) => {


setText(event.target.value);
};

return (
<div>
<input type="text" value={text} onChange={handleChange} />
<p>Input Value: {text}</p>
</div>
);
}

export default ControlledInput;

• The value attribute is bound to text.


• The onChange event updates the state with setText(event.target.value).

2. Handling Multiple Inputs

When dealing with multiple inputs, the state should store an object containing all field values.

Example: Handling Multiple Inputs


import React, { useState } from "react";

function UserForm() {
const [formData, setFormData] = useState({ name: "", email: "" });
const handleChange = (event) => {
setFormData({ ...formData, [event.target.name]: event.target.value });
};

return (
<div>
<input type="text" name="name" value={formData.name}
onChange={handleChange} placeholder="Name" />
<input type="email" name="email" value={formData.email}
onChange={handleChange} placeholder="Email" />
<p>Name: {formData.name}</p>
<p>Email: {formData.email}</p>
</div>
);
}

export default UserForm;

• The state is an object (formData) holding multiple values.


• The [event.target.name] dynamically updates the correct field.

3. Handling Form Submission

When the form is submitted, we prevent the default behavior and handle the input values.

Example: Controlled Form Submission


import React, { useState } from "react";

function SignupForm() {
const [formData, setFormData] = useState({ username: "", password: "" });

const handleChange = (event) => {


setFormData({ ...formData, [event.target.name]: event.target.value });
};

const handleSubmit = (event) => {


event.preventDefault();
alert(`Username: ${formData.username}, Password: ${formData.password}`);
};

return (
<form onSubmit={handleSubmit}>
<input type="text" name="username" value={formData.username}
onChange={handleChange} placeholder="Username" />
<input type="password" name="password" value={formData.password}
onChange={handleChange} placeholder="Password" />
<button type="submit">Submit</button>
</form>
);
}
export default SignupForm;

• handleSubmit prevents form refresh (event.preventDefault()).


• alert() displays the submitted data.

4. Handling Select, Checkbox, and Textarea


Example: Handling Different Inputs
import React, { useState } from "react";

function PreferencesForm() {
const [preferences, setPreferences] = useState({
gender: "male",
subscribe: false,
comments: "",
});

const handleChange = (event) => {


const { name, type, checked, value } = event.target;
setPreferences({
...preferences,
[name]: type === "checkbox" ? checked : value,
});
};

return (
<form>
<select name="gender" value={preferences.gender}
onChange={handleChange}>
<option value="male">Male</option>
<option value="female">Female</option>
</select>

<input type="checkbox" name="subscribe" checked={preferences.subscribe}


onChange={handleChange} />
<label>Subscribe to newsletter</label>

<textarea name="comments" value={preferences.comments}


onChange={handleChange} placeholder="Write a comment..." />

<p>Gender: {preferences.gender}</p>
<p>Subscribed: {preferences.subscribe ? "Yes" : "No"}</p>
<p>Comments: {preferences.comments}</p>
</form>
);
}

export default PreferencesForm;

• The select, checkbox, and textarea elements are controlled using state.
• The checked property manages checkboxes.

Conclusion

Controlled components keep form elements synchronized with React state, making data handling
easier. By using useState and event handlers, React efficiently manages input fields, multiple
values, and form submissions.

Here's a small React Form Handling Project that uses all the topics covered so far:

✅ Functional Components
✅ CSS Styling
✅ Click Events
✅ useState Hook
✅ Lists and Keys
✅ Props & Prop Drilling
✅ Controlled Form Inputs

Project: User Registration Form

This project includes:

• A User Form for registration


• A User List to display registered users
• Proper state management and prop drilling
• Dynamic updates using controlled components

Project Structure
/user-registration
├── src
│ ├── components
│ │ ├── UserForm.js
│ │ ├── UserList.js
│ │ ├── UserItem.js
│ ├── App.js
│ ├── index.js
├── package.json
├── public
├── README.md
1. UserForm.js (Controlled Form & Props)

This component handles form input and submits new users.

import React, { useState } from "react";

function UserForm({ addUser }) {


const [formData, setFormData] = useState({ name: "", email: "" });

const handleChange = (event) => {


setFormData({ ...formData, [event.target.name]: event.target.value });
};

const handleSubmit = (event) => {


event.preventDefault();
if (formData.name && formData.email) {
addUser(formData);
setFormData({ name: "", email: "" }); // Reset form after submission
}
};

return (
<form onSubmit={handleSubmit} className="user-form">
<input type="text" name="name" value={formData.name}
onChange={handleChange} placeholder="Enter Name" required />
<input type="email" name="email" value={formData.email}
onChange={handleChange} placeholder="Enter Email" required />
<button type="submit">Register</button>
</form>
);
}

export default UserForm;

• Controlled input fields with useState


• Calls addUser (prop) to update user list

2. UserList.js (Lists, Keys, Props & Prop Drilling)

Displays the list of registered users.

import React from "react";


import UserItem from "./UserItem";

function UserList({ users }) {


return (
<div className="user-list">
<h2>Registered Users</h2>
<ul>
{users.map((user, index) => (
<UserItem key={index} user={user} />
))}
</ul>
</div>
);
}

export default UserList;

• Maps through users and displays them using the UserItem component
• Prop drilling: users data is passed down

3. UserItem.js (Props & JSX)

Single user item component.

import React from "react";

function UserItem({ user }) {


return (
<li className="user-item">
<strong>{user.name}</strong> - {user.email}
</li>
);
}

export default UserItem;

• Simple functional component that receives a user as a prop

4. App.js (useState & Click Events)

Handles user state and connects components.

import React, { useState } from "react";


import UserForm from "./components/UserForm";
import UserList from "./components/UserList";
import "./App.css";

function App() {
const [users, setUsers] = useState([]);

const addUser = (newUser) => {


setUsers([...users, newUser]);
};

return (
<div className="app">
<h1>User Registration</h1>
<UserForm addUser={addUser} />
<UserList users={users} />
</div>
);
}

export default App;

• Manages the list of users using useState


• Passes the addUser function as a prop

5. App.css (CSS Styling in React)

Basic styling for the project.

body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}

.app {
width: 50%;
margin: auto;
text-align: center;
}

.user-form {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 20px;
}

.user-form input {
padding: 8px;
font-size: 16px;
}

button {
background-color: #007bff;
color: white;
border: none;
padding: 10px;
cursor: pointer;
}

.user-list ul {
list-style: none;
padding: 0;
}

.user-item {
background-color: white;
margin: 5px;
padding: 10px;
border-radius: 5px;
}

• Styled form, buttons, and user list

How to Run the Project

1. Create React App


2. npx create-react-app user-registration
3. cd user-registration
4. Replace the src/ files with the above code
5. Run the app
6. npm start

Conclusion

This project integrates multiple React fundamentals into a real-world example:

• Controlled components for form handling


• useState for dynamic state updates
• Lists & Keys for rendering user lists
• Props & Prop Drilling for data sharing
• Click events for form submission
• CSS Styling for better UI

Would you like any additional features like local storage or user deletion?

Using JSON Server for a REST API in React

JSON Server is a lightweight, easy-to-use mock REST API that allows React applications to
perform CRUD operations (Create, Read, Update, Delete) using fetch or axios. It’s great for
prototyping and testing React projects.

1. Installing JSON Server

To install JSON Server, run:

npm install -g json-server


OR, install locally for your project:

npm install json-server

2. Setting Up a Mock Database

Create a file named db.json in your project root and add sample data:

{
"users": [
{ "id": 1, "name": "John Doe", "email": "[email protected]" },
{ "id": 2, "name": "Jane Smith", "email": "[email protected]" }
]
}

• The users array simulates a database table.


• Each object represents a user record with an id, name, and email.

3. Running JSON Server

Start the JSON Server using:

json-server --watch db.json --port 5000

• --watch: Watches for changes in db.json.


• --port 5000: Runs the API on port 5000 (default is 3000).

You'll see output like:

Resources
http://localhost:5000/users

Now, you can send GET, POST, PUT, DELETE requests to http://localhost:5000/users.

4. Integrating JSON Server with React

Modify the User Registration Project to fetch and update users from JSON Server.
4.1 Fetching Users from JSON Server

Update UserList.js to Fetch Data

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


import UserItem from "./UserItem";

function UserList() {
const [users, setUsers] = useState([]);

useEffect(() => {
fetch("http://localhost:5000/users")
.then((response) => response.json())
.then((data) => setUsers(data))
.catch((error) => console.error("Error fetching users:", error));
}, []);

return (
<div className="user-list">
<h2>Registered Users</h2>
<ul>
{users.map((user) => (
<UserItem key={user.id} user={user} />
))}
</ul>
</div>
);
}

export default UserList;

• Uses useEffect to fetch users from JSON Server on component mount.


• Stores the response in users state.

4.2 Adding Users to JSON Server

Update UserForm.js to Send Data to JSON Server

import React, { useState } from "react";

function UserForm({ refreshUsers }) {


const [formData, setFormData] = useState({ name: "", email: "" });

const handleChange = (event) => {


setFormData({ ...formData, [event.target.name]: event.target.value });
};

const handleSubmit = async (event) => {


event.preventDefault();
if (formData.name && formData.email) {
await fetch("http://localhost:5000/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(formData),
});
setFormData({ name: "", email: "" });
refreshUsers(); // Refresh user list after adding
}
};

return (
<form onSubmit={handleSubmit} className="user-form">
<input type="text" name="name" value={formData.name}
onChange={handleChange} placeholder="Enter Name" required />
<input type="email" name="email" value={formData.email}
onChange={handleChange} placeholder="Enter Email" required />
<button type="submit">Register</button>
</form>
);
}

export default UserForm;

• Sends a POST request to JSON Server when submitting the form.


• Calls refreshUsers() (passed as a prop) to reload the user list.

4.3 Updating & Deleting Users


Updating a User (Using PUT)

Modify UserItem.js to include an edit button:

import React, { useState } from "react";

function UserItem({ user, refreshUsers }) {


const [editing, setEditing] = useState(false);
const [updatedUser, setUpdatedUser] = useState(user);

const handleUpdate = async () => {


await fetch(`http://localhost:5000/users/${user.id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(updatedUser),
});
setEditing(false);
refreshUsers();
};

return (
<li className="user-item">
{editing ? (
<>
<input type="text" value={updatedUser.name} onChange={(e) =>
setUpdatedUser({ ...updatedUser, name: e.target.value })} />
<input type="email" value={updatedUser.email} onChange={(e) =>
setUpdatedUser({ ...updatedUser, email: e.target.value })} />
<button onClick={handleUpdate}>Save</button>
</>
) : (
<>
<strong>{user.name}</strong> - {user.email}
<button onClick={() => setEditing(true)}>Edit</button>
</>
)}
</li>
);
}

export default UserItem;

• Enables inline editing for user details.


• Sends a PUT request to update user data.

Deleting a User (Using DELETE)

Modify UserItem.js to include a delete button:

const handleDelete = async () => {


await fetch(`http://localhost:5000/users/${user.id}`, {
method: "DELETE",
});
refreshUsers();
};

<button onClick={handleDelete}>Delete</button>

• Sends a DELETE request to remove a user from JSON Server.

4.4 Updating App.js to Refresh Users

Modify App.js to refresh users after changes:

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


import UserForm from "./components/UserForm";
import UserList from "./components/UserList";
import "./App.css";

function App() {
const [users, setUsers] = useState([]);
const fetchUsers = () => {
fetch("http://localhost:5000/users")
.then((response) => response.json())
.then((data) => setUsers(data))
.catch((error) => console.error("Error fetching users:", error));
};

useEffect(() => {
fetchUsers();
}, []);

return (
<div className="app">
<h1>User Registration</h1>
<UserForm refreshUsers={fetchUsers} />
<UserList users={users} refreshUsers={fetchUsers} />
</div>
);
}

export default App;

• fetchUsers() updates the state when data changes.


• Passed to UserForm and UserList to refresh after adding/deleting users.

Conclusion

Now, our React User Registration App is fully integrated with a REST API using JSON
Server. It supports:
✅ Fetching users (GET)
✅ Adding new users (POST)
✅ Updating user details (PUT)
✅ Deleting users (DELETE)

Would you like any additional features, such as pagination or filtering?

Fetching Data from an API in React

Fetching data from an API is an essential part of building dynamic React applications. React
provides various ways to fetch data, including using fetch API, Axios, and third-party libraries
like React Query.
1. Fetching Data with the Fetch API
Example: Fetching Users from JSONPlaceholder API
import React, { useState, useEffect } from "react";

function UserList() {
const [users, setUsers] = useState([]);

useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => response.json())
.then((data) => setUsers(data))
.catch((error) => console.error("Error fetching data:", error));
}, []);

return (
<div>
<h2>Users List</h2>
<ul>
{users.map((user) => (
<li key={user.id}>{user.name} - {user.email}</li>
))}
</ul>
</div>
);
}

export default UserList;

Explanation

• useEffect(() => {}, []): Runs only once when the component mounts.
• fetch(): Makes a GET request to the API.
• .then(response => response.json()): Converts response to JSON.
• .then(data => setUsers(data)): Stores data in state.
• catch(error => console.error()): Handles errors.

2. Fetching Data with Axios

Axios is a popular alternative to fetch(), providing better error handling and automatic JSON
conversion.

Installing Axios
npm install axios
Example Using Axios
import React, { useState, useEffect } from "react";
import axios from "axios";

function UserList() {
const [users, setUsers] = useState([]);

useEffect(() => {
axios.get("https://jsonplaceholder.typicode.com/users")
.then(response => setUsers(response.data))
.catch(error => console.error("Error fetching data:", error));
}, []);

return (
<div>
<h2>Users List</h2>
<ul>
{users.map((user) => (
<li key={user.id}>{user.name} - {user.email}</li>
))}
</ul>
</div>
);
}

export default UserList;

Advantages of Axios Over Fetch

• Automatic JSON Parsing (No need for .json()).


• Better Error Handling (Handles HTTP status errors automatically).
• Supports Request Interceptors (Useful for authentication).

3. Fetching Data on Button Click

Instead of fetching on page load, you can fetch data on user action (button click).

import React, { useState } from "react";


import axios from "axios";

function FetchUsers() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(false);

const fetchData = async () => {


setLoading(true);
try {
const response = await
axios.get("https://jsonplaceholder.typicode.com/users");
setUsers(response.data);
} catch (error) {
console.error("Error fetching data:", error);
}
setLoading(false);
};

return (
<div>
<button onClick={fetchData} disabled={loading}>
{loading ? "Loading..." : "Fetch Users"}
</button>
<ul>
{users.map((user) => (
<li key={user.id}>{user.name} - {user.email}</li>
))}
</ul>
</div>
);
}

export default FetchUsers;

Explanation

• Uses useState to track loading state.


• Button click triggers fetchData(), which fetches user data.
• Disables the button while fetching to prevent multiple requests.

4. Fetching Data with React Query (Best for Large Apps)

React Query simplifies data fetching, caching, and automatic re-fetching.

Installing React Query


npm install @tanstack/react-query

Example Using React Query


import React from "react";
import { useQuery } from "@tanstack/react-query";
import axios from "axios";

function UserList() {
const { data: users, error, isLoading } = useQuery({
queryKey: ["users"],
queryFn: async () => {
const response = await
axios.get("https://jsonplaceholder.typicode.com/users");
return response.data;
}
});
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error loading users.</p>;

return (
<div>
<h2>Users List</h2>
<ul>
{users.map((user) => (
<li key={user.id}>{user.name} - {user.email}</li>
))}
</ul>
</div>
);
}

export default UserList;

Why Use React Query?

• Handles caching & re-fetching automatically.


• Shows loading & error states without extra state management.
• Efficient for large apps with frequent API requests.

Conclusion

There are multiple ways to fetch data in React:


✅ fetch API – Simple and built-in.
✅ Axios – More features and better error handling.
✅ Button Click – Fetch data on demand.
✅ React Query – Best for large applications with caching.

Would you like an example of POST (creating new data) or DELETE (removing data)
requests as well?

React CRUD Operations (Create, Read, Update, Delete)

CRUD (Create, Read, Update, Delete) operations are essential in any full-stack application. In
this guide, we'll build a React CRUD App using JSON Server as a fake REST API.
1. Setup JSON Server (Fake API)
Step 1: Install JSON Server
npm install -g json-server

Step 2: Create a db.json File

Create a file named db.json in your project root and add sample data:

{
"users": [
{ "id": 1, "name": "John Doe", "email": "[email protected]" },
{ "id": 2, "name": "Jane Doe", "email": "[email protected]" }
]
}

Step 3: Start JSON Server

Run the following command:

json-server --watch db.json --port 5000

• Your API will be available at http://localhost:5000/users

2. Setting Up React Project


Step 1: Create a React App
npx create-react-app react-crud-app
cd react-crud-app
npm install axios

• Axios is used to handle API requests.

3. Implementing CRUD Operations

We'll create a User Management System where users can be added, viewed, updated, and
deleted.

Step 1: Create UserList.js (Read and Delete)


import React, { useEffect, useState } from "react";
import axios from "axios";
function UserList({ onEdit }) {
const [users, setUsers] = useState([]);

// Fetch Users
useEffect(() => {
axios.get("http://localhost:5000/users")
.then(response => setUsers(response.data))
.catch(error => console.error("Error fetching users:", error));
}, []);

// Delete User
const deleteUser = (id) => {
axios.delete(`http://localhost:5000/users/${id}`)
.then(() => setUsers(users.filter(user => user.id !== id)))
.catch(error => console.error("Error deleting user:", error));
};

return (
<div>
<h2>User List</h2>
<ul>
{users.map(user => (
<li key={user.id}>
{user.name} - {user.email}
<button onClick={() => onEdit(user)}>Edit</button>
<button onClick={() => deleteUser(user.id)}>Delete</button>
</li>
))}
</ul>
</div>
);
}

export default UserList;

Explanation

• Fetch Users using axios.get().


• Delete Users using axios.delete() and update state.

Step 2: Create UserForm.js (Create and Update)


import React, { useState, useEffect } from "react";
import axios from "axios";

function UserForm({ selectedUser, refreshUsers }) {


const [user, setUser] = useState({ name: "", email: "" });

useEffect(() => {
if (selectedUser) {
setUser(selectedUser);
}
}, [selectedUser]);
// Handle Input Change
const handleChange = (e) => {
setUser({ ...user, [e.target.name]: e.target.value });
};

// Handle Form Submit (Create/Update)


const handleSubmit = (e) => {
e.preventDefault();
if (user.id) {
// Update User
axios.put(`http://localhost:5000/users/${user.id}`, user)
.then(() => refreshUsers());
} else {
// Create User
axios.post("http://localhost:5000/users", user)
.then(() => refreshUsers());
}
setUser({ name: "", email: "" });
};

return (
<form onSubmit={handleSubmit}>
<h2>{user.id ? "Edit User" : "Add User"}</h2>
<input type="text" name="name" value={user.name}
onChange={handleChange} placeholder="Name" required />
<input type="email" name="email" value={user.email}
onChange={handleChange} placeholder="Email" required />
<button type="submit">{user.id ? "Update" : "Create"}</button>
</form>
);
}

export default UserForm;

Explanation

• Create User using axios.post().


• Update User using axios.put().
• Uses a single form for both create and update.

Step 3: Create App.js (Manage State)


import React, { useState } from "react";
import UserList from "./UserList";
import UserForm from "./UserForm";

function App() {
const [selectedUser, setSelectedUser] = useState(null);

// Refresh User List


const refreshUsers = () => setSelectedUser(null);
return (
<div>
<h1>React CRUD App</h1>
<UserForm selectedUser={selectedUser} refreshUsers={refreshUsers} />
<UserList onEdit={setSelectedUser} />
</div>
);
}

export default App;

Explanation

• Manages user selection for editing.


• Refreshes the list after adding, updating, or deleting a user.

4. Running the Project


Step 1: Start JSON Server
json-server --watch db.json --port 5000

Step 2: Start React App


npm start

• Open http://localhost:3000 in the browser.

Conclusion

Create Users using axios.post().


Read Users using axios.get().
Update Users using axios.put().
Delete Users using axios.delete().

This covers the full CRUD operations in React with JSON Server. Would you like to extend
this with a better UI using Material-UI or Tailwind CSS?

Here's a Fetch Data Challenge project that will help you practice API calls, state management,
and rendering data dynamically in React.
Project: User Data Fetcher
Goal:

• Fetch user data from an API.


• Display user details in a styled UI.
• Implement a "Load More Users" feature.
• Implement a search filter to find users easily.

1. Setup the React Project


Step 1: Create React App
npx create-react-app fetch-data-challenge
cd fetch-data-challenge
npm install axios

• We'll use Axios for API calls.

2. Fetch and Display Data


Step 2: Create UserList.js

This component fetches data from an API and displays it.

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


import axios from "axios";

function UserList() {
const [users, setUsers] = useState([]);
const [search, setSearch] = useState("");
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(false);

// Fetch Users from API


const fetchUsers = async () => {
setLoading(true);
try {
const response = await
axios.get(`https://randomuser.me/api/?results=5&page=${page}`);
setUsers([...users, ...response.data.results]);
} catch (error) {
console.error("Error fetching users:", error);
}
setLoading(false);
};

useEffect(() => {
fetchUsers();
}, [page]);

// Load More Users


const loadMoreUsers = () => {
setPage(page + 1);
};

return (
<div>
<h1>User List</h1>
<input
type="text"
placeholder="Search users..."
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
<ul>
{users
.filter(user =>
user.name.first.toLowerCase().includes(search.toLowerCase()) ||
user.name.last.toLowerCase().includes(search.toLowerCase())
)
.map((user, index) => (
<li key={index}>
<img src={user.picture.thumbnail} alt={user.name.first} />
{user.name.first} {user.name.last} - {user.email}
</li>
))}
</ul>
<button onClick={loadMoreUsers} disabled={loading}>
{loading ? "Loading..." : "Load More Users"}
</button>
</div>
);
}

export default UserList;

3. Integrate with App.js

Replace App.js content with:

import React from "react";


import UserList from "./UserList";

function App() {
return (
<div>
<UserList />
</div>
);
}

export default App;

4. Run the Project


npm start

• Open http://localhost:3000
• Try searching for a user by first or last name.
• Click "Load More Users" to fetch more users.

Conclusion

Fetch API data dynamically


Implement a search filter
Load more users on demand

Would you like to enhance this with pagination or a better UI using Tailwind CSS?

React Router: Navigation in React

React Router is a library used to handle navigation in React applications. It enables single-page
applications (SPAs) to have multiple views without reloading the page.

1. Install React Router


npm install react-router-dom

2. Setup React Router in index.js

Wrap the application inside <BrowserRouter>:

import React from "react";


import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import App from "./App";

ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);

3. Create Pages
(1) Home Page (Home.js)
import React from "react";

function Home() {
return <h1>Welcome to the Home Page</h1>;
}

export default Home;

(2) About Page (About.js)


import React from "react";

function About() {
return <h1>About Us</h1>;
}

export default About;

(3) Contact Page (Contact.js)


import React from "react";

function Contact() {
return <h1>Contact Us</h1>;
}

export default Contact;

4. Define Routes in App.js

Use the <Routes> component to define navigation paths.

import React from "react";


import { Routes, Route } from "react-router-dom";
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";
import Navbar from "./Navbar";

function App() {
return (
<div>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</div>
);
}

export default App;

5. Create Navigation Menu (Navbar.js)


import React from "react";
import { Link } from "react-router-dom";

function Navbar() {
return (
<nav>
<Link to="/">Home</Link> |
<Link to="/about">About</Link> |
<Link to="/contact">Contact</Link>
</nav>
);
}

export default Navbar;

6. Run the Project


npm start

• Open http://localhost:3000
• Click on "About" or "Contact" in the navbar to navigate.

Conclusion

Navigation without page reloads


Separate components for each page
React Router for SPAs

Would you like to add protected routes (authentication-based) or a 404 Not Found page?
React Router Hooks & Links

React Router provides various hooks and <Link> components to navigate between pages
dynamically.

1. Install React Router

If not installed, run:

npm install react-router-dom

2. React Router Hooks


(1) useNavigate() – Programmatic Navigation

Use useNavigate() to navigate between pages dynamically.

import React from "react";


import { useNavigate } from "react-router-dom";

function Home() {
const navigate = useNavigate();

return (
<div>
<h1>Home Page</h1>
<button onClick={() => navigate("/about")}>Go to About</button>
</div>
);
}

export default Home;

Clicking the button navigates to /about.

(2) useParams() – Get Dynamic Route Parameters

Retrieve URL parameters using useParams().

Example: Dynamic User Profile (User.js)


import React from "react";
import { useParams } from "react-router-dom";
function User() {
const { id } = useParams();

return <h1>Profile Page of User ID: {id}</h1>;


}

export default User;


Define Route in App.js
<Route path="/user/:id" element={<User />} />

Visiting /user/5 displays User ID 5.

(3) useLocation() – Get Current Route Information

Get the current route pathname.

import React from "react";


import { useLocation } from "react-router-dom";

function CurrentLocation() {
const location = useLocation();

return <h1>Current Page: {location.pathname}</h1>;


}

export default CurrentLocation;

Visiting /about displays "Current Page: /about".

3. React Router <Link> & <NavLink>


(1) <Link> – Navigation Without Page Reload

Use <Link> instead of <a> to prevent full page reloads.

import React from "react";


import { Link } from "react-router-dom";

function Navbar() {
return (
<nav>
<Link to="/">Home</Link> |
<Link to="/about">About</Link> |
<Link to="/contact">Contact</Link>
</nav>
);
}

export default Navbar;

Clicking links changes pages without reloading.

(2) <NavLink> – Active Link Styling

Use <NavLink> to add active styling.

import React from "react";


import { NavLink } from "react-router-dom";

function Navbar() {
return (
<nav>
<NavLink to="/" style={({ isActive }) => ({ fontWeight: isActive ?
"bold" : "normal" })}>
Home
</NavLink> |
<NavLink to="/about" style={({ isActive }) => ({ fontWeight: isActive ?
"bold" : "normal" })}>
About
</NavLink> |
<NavLink to="/contact" style={({ isActive }) => ({ fontWeight: isActive
? "bold" : "normal" })}>
Contact
</NavLink>
</nav>
);
}

export default Navbar;

Active link is bold.

4. Define Routes in App.js


import React from "react";
import { Routes, Route } from "react-router-dom";
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";
import User from "./User";
import Navbar from "./Navbar";

function App() {
return (
<div>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
<Route path="/user/:id" element={<User />} />
</Routes>
</div>
);
}

export default App;

5. Run the Project


npm start

• Open http://localhost:3000
• Click on links to navigate between pages.
• Try /user/123 in the browser.

Conclusion

useNavigate() – Programmatic Navigation


useParams() – Get Dynamic Route Parameters
useLocation() – Get Current Route Info
<Link> – Page Navigation Without Reload
<NavLink> – Active Link Styling

Would you like to add protected routes (authentication-based navigation)?

React CSS Width & Height Settings

In React, you can set width and height using inline styles, CSS classes, styled-components, or
Tailwind CSS.

1. Using Inline Styles

React uses a JavaScript object for inline styles.

import React from "react";


function Box() {
const boxStyle = {
width: "200px",
height: "100px",
backgroundColor: "lightblue",
textAlign: "center",
lineHeight: "100px",
};

return <div style={boxStyle}>Inline Styled Box</div>;


}

export default Box;

Width: 200px, Height: 100px, Blue Background

2. Using CSS Classes

Define styles in a CSS file (styles.css).

styles.css
.box {
width: 250px;
height: 120px;
background-color: lightgreen;
text-align: center;
line-height: 120px;
}

Apply in Component
import React from "react";
import "./styles.css";

function Box() {
return <div className="box">CSS Styled Box</div>;
}

export default Box;

Uses external CSS for styling

3. Using styled-components (CSS-in-JS)

Install styled-components:
npm install styled-components

Create a Styled Box


import React from "react";
import styled from "styled-components";

const StyledBox = styled.div`


width: 300px;
height: 150px;
background-color: coral;
text-align: center;
line-height: 150px;
`;

function Box() {
return <StyledBox>Styled Components Box</StyledBox>;
}

export default Box;

Uses styled-components for dynamic styling

4. Using Tailwind CSS (Utility Classes)

Install Tailwind:

npm install tailwindcss

Apply Tailwind Classes


import React from "react";

function Box() {
return <div className="w-64 h-32 bg-blue-500 text-white text-center flex
items-center justify-center">Tailwind Box</div>;
}

export default Box;

Easy width (w-64) and height (h-32) control

Conclusion

Inline Styles – Quick and dynamic


CSS Classes – Organized and reusable
Styled Components – Component-level styling
Tailwind CSS – Utility-first approach

Which method do you prefer for your project?

Axios API Requests in React

Axios is a popular library for making HTTP requests in React. It supports GET, POST, PUT,
DELETE requests and handles errors efficiently.

1. Install Axios

Run the following command in your React project:

npm install axios

2. Making API Requests with Axios

Create an API service (api.js) to centralize API calls.

(1) GET Request – Fetch Data from API


import React, { useEffect, useState } from "react";
import axios from "axios";

function FetchData() {
const [data, setData] = useState([]);

useEffect(() => {
axios.get("https://jsonplaceholder.typicode.com/posts")
.then((response) => setData(response.data))
.catch((error) => console.error("Error fetching data:", error));
}, []);

return (
<div>
<h2>Posts</h2>
{data.slice(0, 5).map((post) => (
<p key={post.id}>{post.title}</p>
))}
</div>
);
}

export default FetchData;


Fetches posts from an API and displays the first 5.

(2) POST Request – Add Data to API


import React, { useState } from "react";
import axios from "axios";

function CreatePost() {
const [title, setTitle] = useState("");

const handleSubmit = async () => {


try {
const response = await
axios.post("https://jsonplaceholder.typicode.com/posts", {
title,
body: "This is a new post",
userId: 1
});
console.log("Post Created:", response.data);
} catch (error) {
console.error("Error creating post:", error);
}
};

return (
<div>
<input type="text" value={title} onChange={(e) =>
setTitle(e.target.value)} placeholder="Enter title" />
<button onClick={handleSubmit}>Create Post</button>
</div>
);
}

export default CreatePost;

Sends new post data to the API.

(3) PUT Request – Update Data


import React, { useState } from "react";
import axios from "axios";

function UpdatePost() {
const [title, setTitle] = useState("");

const handleUpdate = async () => {


try {
const response = await
axios.put("https://jsonplaceholder.typicode.com/posts/1", {
id: 1,
title,
body: "Updated post content",
userId: 1
});
console.log("Post Updated:", response.data);
} catch (error) {
console.error("Error updating post:", error);
}
};

return (
<div>
<input type="text" value={title} onChange={(e) =>
setTitle(e.target.value)} placeholder="Update title" />
<button onClick={handleUpdate}>Update Post</button>
</div>
);
}

export default UpdatePost;

Updates post ID 1 in the API.

(4) DELETE Request – Remove Data


import React from "react";
import axios from "axios";

function DeletePost() {
const handleDelete = async () => {
try {
await axios.delete("https://jsonplaceholder.typicode.com/posts/1");
console.log("Post Deleted");
} catch (error) {
console.error("Error deleting post:", error);
}
};

return <button onClick={handleDelete}>Delete Post</button>;


}

export default DeletePost;

Deletes post ID 1 from the API.

5. Using All API Calls in App.js


import React from "react";
import FetchData from "./FetchData";
import CreatePost from "./CreatePost";
import UpdatePost from "./UpdatePost";
import DeletePost from "./DeletePost";

function App() {
return (
<div>
<FetchData />
<CreatePost />
<UpdatePost />
<DeletePost />
</div>
);
}

export default App;

Conclusion

GET – Fetch data from API


POST – Send data to API
PUT – Update data in API
DELETE – Remove data from API

Would you like to integrate loading states or error handling for better UX?

Custom Hooks in React

A custom hook is a reusable function in React that encapsulates logic using built-in hooks like
useState, useEffect, or useContext. It helps reduce code duplication and improves
maintainability.

1. Creating a Custom Hook (useFetch.js)

Let's create a hook to fetch data from an API using useEffect and useState.

import { useState, useEffect } from "react";


import axios from "axios";

function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
setLoading(true);
axios.get(url)
.then((response) => {
setData(response.data);
setLoading(false);
})
.catch((error) => {
setError(error);
setLoading(false);
});
}, [url]);

return { data, loading, error };


}

export default useFetch;

Encapsulates API fetching logic


Reusable in multiple components

2. Using the Custom Hook in a Component

Now, let's use useFetch inside a component to display posts.

import React from "react";


import useFetch from "./useFetch";

function PostList() {
const { data, loading, error } =
useFetch("https://jsonplaceholder.typicode.com/posts");

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


if (error) return <p>Error fetching data!</p>;

return (
<div>
<h2>Posts</h2>
{data.slice(0, 5).map((post) => (
<p key={post.id}>{post.title}</p>
))}
</div>
);
}

export default PostList;

Fetches and displays the first 5 posts.


Handles loading and error states.
3. Custom Hook for Local Storage (useLocalStorage.js)

This hook allows storing and retrieving values from localStorage.

import { useState, useEffect } from "react";

function useLocalStorage(key, initialValue) {


const [value, setValue] = useState(() => {
const storedValue = localStorage.getItem(key);
return storedValue ? JSON.parse(storedValue) : initialValue;
});

useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);

return [value, setValue];


}

export default useLocalStorage;

Stores values persistently


Automatically updates localStorage when the state changes

Using useLocalStorage in a Component


import React from "react";
import useLocalStorage from "./useLocalStorage";

function Counter() {
const [count, setCount] = useLocalStorage("count", 0);

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

export default Counter;

Saves the counter value persistently even after a page refresh.

4. Custom Hook for Handling Forms (useForm.js)

This hook simplifies form handling with useState.


import { useState } from "react";

function useForm(initialValues) {
const [values, setValues] = useState(initialValues);

const handleChange = (e) => {


setValues({
...values,
[e.target.name]: e.target.value,
});
};

return { values, handleChange };


}

export default useForm;

Manages form state dynamically


Prevents repetitive useState calls in components

Using useForm in a Component


import React from "react";
import useForm from "./useForm";

function LoginForm() {
const { values, handleChange } = useForm({ email: "", password: "" });

return (
<div>
<input type="email" name="email" value={values.email}
onChange={handleChange} placeholder="Email" />
<input type="password" name="password" value={values.password}
onChange={handleChange} placeholder="Password" />
<button>Submit</button>
</div>
);
}

export default LoginForm;

Handles form inputs dynamically


Prevents managing each input state separately
Conclusion

useFetch – Fetch data from an API


useLocalStorage – Store data persistently
useForm – Manage form inputs

Would you like a custom hook for authentication or theme switching?

React Custom Hooks with Axios and useEffect

A custom hook is a reusable function that allows us to encapsulate logic using React hooks like
useState, useEffect, and useRef. Combining Axios and async/await inside useEffect makes
API calls more efficient and reusable across multiple components.

1. Create a Custom Hook (useAxios.js)

This hook handles GET, POST, PUT, DELETE requests using Axios.

import { useState, useEffect } from "react";


import axios from "axios";

function useAxios(url, method = "GET", body = null, dependencies = []) {


const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
let response;
if (method === "GET") {
response = await axios.get(url);
} else if (method === "POST") {
response = await axios.post(url, body);
} else if (method === "PUT") {
response = await axios.put(url, body);
} else if (method === "DELETE") {
response = await axios.delete(url);
}

setData(response.data);
} catch (err) {
setError(err);
}
setLoading(false);
};
fetchData();
}, dependencies);

return { data, loading, error };


}

export default useAxios;

Handles API calls dynamically


Supports GET, POST, PUT, DELETE
Uses useEffect with async/await

2. Using useAxios for GET Request

Fetching posts from an API and displaying them.

import React from "react";


import useAxios from "./useAxios";

function PostList() {
const { data, loading, error } =
useAxios("https://jsonplaceholder.typicode.com/posts");

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


if (error) return <p>Error fetching data!</p>;

return (
<div>
<h2>Posts</h2>
{data.slice(0, 5).map((post) => (
<p key={post.id}>{post.title}</p>
))}
</div>
);
}

export default PostList;

Automatically fetches data on mount


Handles loading and error states

3. Using useAxios for POST Request

Sending data to an API.

import React, { useState } from "react";


import useAxios from "./useAxios";

function CreatePost() {
const [title, setTitle] = useState("");
const { data, loading, error } = useAxios(
"https://jsonplaceholder.typicode.com/posts",
"POST",
{ title, body: "New Post", userId: 1 },
[title]
);

return (
<div>
<input type="text" value={title} onChange={(e) =>
setTitle(e.target.value)} placeholder="Enter title" />
<button disabled={loading}>Create Post</button>
{error && <p>Error creating post!</p>}
{data && <p>Post Created: {data.title}</p>}
</div>
);
}

export default CreatePost;

Triggers API call when title changes


Handles response and displays created post

4. Using useAxios for PUT and DELETE Requests

Updating and deleting posts.

import React from "react";


import useAxios from "./useAxios";

function UpdateDeletePost() {
const updateData = { title: "Updated Title", body: "Updated Content",
userId: 1 };
const { data: updatedPost, error: updateError } = useAxios(
"https://jsonplaceholder.typicode.com/posts/1",
"PUT",
updateData,
[]
);

const { data: deletedPost, error: deleteError } = useAxios(


"https://jsonplaceholder.typicode.com/posts/1",
"DELETE",
null,
[]
);

return (
<div>
{updateError && <p>Error updating post!</p>}
{updatedPost && <p>Post Updated: {updatedPost.title}</p>}

{deleteError && <p>Error deleting post!</p>}


{deletedPost && <p>Post Deleted Successfully!</p>}
</div>
);
}

export default UpdateDeletePost;

Handles PUT request for updating data


Handles DELETE request for removing data

5. Integrating All Requests in App.js


import React from "react";
import PostList from "./PostList";
import CreatePost from "./CreatePost";
import UpdateDeletePost from "./UpdateDeletePost";

function App() {
return (
<div>
<PostList />
<CreatePost />
<UpdateDeletePost />
</div>
);
}

export default App;

Conclusion

Reusable useAxios hook for API calls


Handles GET, POST, PUT, DELETE dynamically
Uses async/await inside useEffect

Would you like to extend this hook for pagination or authentication tokens?

State Management in React


State management in React refers to handling and updating data across components. It ensures
that different parts of an application can access and modify shared data efficiently. React
provides built-in state management using useState and useReducer, while external libraries
like Redux, Recoil, and Zustand help manage complex state structures.

1. State Management with useState

The useState hook is used for managing local component state.

Example: Counter using useState


import React, { useState } from "react";

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

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

export default Counter;

Simple state update inside a single component


Best for managing small, independent states

2. State Management with useReducer

The useReducer hook is useful for complex state logic involving multiple actions.

Example: Counter using useReducer


import React, { useReducer } from "react";

const reducer = (state, action) => {


switch (action.type) {
case "INCREMENT":
return { count: state.count + 1 };
case "DECREMENT":
return { count: state.count - 1 };
default:
return state;
}
};

function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });

return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: "INCREMENT"
})}>Increment</button>
<button onClick={() => dispatch({ type: "DECREMENT"
})}>Decrement</button>
</div>
);
}

export default Counter;

Best for complex state logic with multiple actions


More scalable than useState

3. State Management with Context API

The Context API allows global state sharing without prop drilling.

Step 1: Create a Context (ThemeContext.js)


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

const ThemeContext = createContext();

export function ThemeProvider({ children }) {


const [theme, setTheme] = useState("light");

const toggleTheme = () => {


setTheme((prev) => (prev === "light" ? "dark" : "light"));
};

return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}

export default ThemeContext;

Step 2: Use Context in a Component


import React, { useContext } from "react";
import ThemeContext from "./ThemeContext";

function ThemeToggle() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<div>
<p>Current Theme: {theme}</p>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
}

export default ThemeToggle;

Step 3: Wrap Components in ThemeProvider (App.js)


import React from "react";
import { ThemeProvider } from "./ThemeContext";
import ThemeToggle from "./ThemeToggle";

function App() {
return (
<ThemeProvider>
<ThemeToggle />
</ThemeProvider>
);
}

export default App;

Avoids prop drilling


Ideal for managing global state (e.g., themes, authentication, user data)

4. State Management with Redux

Redux is an external library used for managing large-scale application states.

Step 1: Install Redux Toolkit


npm install @reduxjs/toolkit react-redux

Step 2: Create a Redux Slice (counterSlice.js)


import { createSlice } from "@reduxjs/toolkit";

const counterSlice = createSlice({


name: "counter",
initialState: { count: 0 },
reducers: {
increment: (state) => {
state.count += 1;
},
decrement: (state) => {
state.count -= 1;
},
},
});

export const { increment, decrement } = counterSlice.actions;


export default counterSlice.reducer;

Step 3: Configure Redux Store (store.js)


import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counterSlice";

export const store = configureStore({


reducer: { counter: counterReducer },
});

Step 4: Provide Store to App (index.js)


import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { store } from "./store";
import Counter from "./Counter";

ReactDOM.render(
<Provider store={store}>
<Counter />
</Provider>,
document.getElementById("root")
);

Step 5: Use Redux in a Component (Counter.js)


import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { increment, decrement } from "./counterSlice";

function Counter() {
const count = useSelector((state) => state.counter.count);
const dispatch = useDispatch();

return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
</div>
);
}

export default Counter;

Best for large applications with multiple global states


Predictable state changes using actions and reducers
5. State Management with Recoil

Recoil is a lightweight alternative to Redux for managing global state.

Step 1: Install Recoil


npm install recoil

Step 2: Create an Atom (state.js)


import { atom } from "recoil";

export const counterState = atom({


key: "counterState",
default: 0,
});

Step 3: Use Recoil State in a Component (Counter.js)


import React from "react";
import { useRecoilState } from "recoil";
import { counterState } from "./state";

function Counter() {
const [count, setCount] = useRecoilState(counterState);

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

export default Counter;

Step 4: Wrap App in RecoilRoot (App.js)


import React from "react";
import { RecoilRoot } from "recoil";
import Counter from "./Counter";

function App() {
return (
<RecoilRoot>
<Counter />
</RecoilRoot>
);
}

export default App;

Simple and flexible alternative to Redux


Minimal boilerplate code
Conclusion

1. useState → Best for small local state.


2. useReducer → Useful for complex state logic.
3. Context API → Good for sharing global state without prop drilling.
4. Redux → Best for large applications requiring structured state management.
5. Recoil → Lightweight and easier alternative to Redux.

Would you like a comparison table for all these approaches?

React Redux
Redux is a state management library used in React applications to manage global state
efficiently. It follows a centralized state management approach, making it easier to handle data
across multiple components.

Why Use Redux in React?

Centralized State – Stores all state in a single global store.


Predictable State Updates – Uses pure functions (reducers) to update state.
Easier Debugging – Redux DevTools help in tracking state changes.
Scalability – Ideal for large applications with complex state management.

1. Install Redux in React App

Before using Redux, install the required dependencies:

npm install @reduxjs/toolkit react-redux

2. Create a Redux Store


Step 1: Create a Redux Slice (counterSlice.js)

A slice represents a piece of the state and defines actions to modify it.

import { createSlice } from "@reduxjs/toolkit";

const counterSlice = createSlice({


name: "counter",
initialState: { count: 0 },
reducers: {
increment: (state) => {
state.count += 1;
},
decrement: (state) => {
state.count -= 1;
},
incrementByAmount: (state, action) => {
state.count += action.payload;
},
},
});

export const { increment, decrement, incrementByAmount } =


counterSlice.actions;
export default counterSlice.reducer;

Step 2: Configure the Redux Store (store.js)

The store holds the global state and integrates all reducers.

import { configureStore } from "@reduxjs/toolkit";


import counterReducer from "./counterSlice";

export const store = configureStore({


reducer: { counter: counterReducer },
});

3. Provide Redux Store to React App

Wrap the entire application with Provider to enable Redux state management.

Modify index.js:
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { store } from "./store";
import Counter from "./Counter";

ReactDOM.render(
<Provider store={store}>
<Counter />
</Provider>,
document.getElementById("root")
);
4. Use Redux in a Component
Step 1: Create Counter Component (Counter.js)

Use useSelector to access state and useDispatch to trigger actions.

import React from "react";


import { useSelector, useDispatch } from "react-redux";
import { increment, decrement, incrementByAmount } from "./counterSlice";

function Counter() {
const count = useSelector((state) => state.counter.count);
const dispatch = useDispatch();

return (
<div>
<h2>Counter: {count}</h2>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
<button onClick={() => dispatch(incrementByAmount(5))}>Increment by
5</button>
</div>
);
}

export default Counter;

useSelector → Accesses the state from Redux store.


useDispatch → Dispatches actions to update the state.

5. Redux Middleware (Optional)

Middleware like Redux Thunk is used for handling asynchronous operations like API calls.

Install Redux Thunk


npm install redux-thunk

Modify store.js to include Thunk


import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counterSlice";
import thunk from "redux-thunk";

export const store = configureStore({


reducer: { counter: counterReducer },
middleware: [thunk],
});
6. Fetch Data using Redux and Thunk
Step 1: Create Async Thunk (userSlice.js)
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";

// Async Thunk for fetching users


export const fetchUsers = createAsyncThunk("users/fetchUsers", async () => {
const response = await fetch("https://jsonplaceholder.typicode.com/users");
return response.json();
});

const userSlice = createSlice({


name: "users",
initialState: { users: [], loading: false },
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchUsers.pending, (state) => {
state.loading = true;
})
.addCase(fetchUsers.fulfilled, (state, action) => {
state.loading = false;
state.users = action.payload;
})
.addCase(fetchUsers.rejected, (state) => {
state.loading = false;
});
},
});

export default userSlice.reducer;

Step 2: Add to Store (store.js)


import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counterSlice";
import userReducer from "./userSlice";

export const store = configureStore({


reducer: {
counter: counterReducer,
users: userReducer
},
});

Step 3: Fetch and Display Users (UserList.js)


import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { fetchUsers } from "./userSlice";

function UserList() {
const dispatch = useDispatch();
const { users, loading } = useSelector((state) => state.users);

useEffect(() => {
dispatch(fetchUsers());
}, [dispatch]);

return (
<div>
<h2>User List</h2>
{loading ? <p>Loading...</p> : users.map((user) => <p
key={user.id}>{user.name}</p>)}
</div>
);
}

export default UserList;

Uses createAsyncThunk for API calls


extraReducers manages async states (loading, success, error)
Efficiently handles large-scale state changes

Conclusion
Key Concepts in Redux:

1. Store → Centralized state storage (store.js).


2. Slice → Manages a part of the state (counterSlice.js).
3. Reducers → Define how the state is modified.
4. Actions → Trigger state changes (increment, decrement).
5. Selectors → Access state in components (useSelector).
6. Dispatch → Sends actions to the store (useDispatch).
7. Middleware → Handles async tasks (redux-thunk).

When to Use Redux?

When the application has multiple components sharing state


When managing complex state logic across components
When the state needs to be predictable and maintainable

Would you like a Redux + React Router integration example next?


How to Deploy a React App to GitHub Pages
GitHub Pages is a free hosting service that allows you to deploy static sites directly from a
GitHub repository. React apps can be deployed easily using GitHub Pages.

1. Prerequisites

• A GitHub account.
• Node.js and npm installed.
• A React project set up using create-react-app.
• A GitHub repository to push your project.

2. Install GitHub Pages Package

Open your terminal and navigate to your React project folder, then install the gh-pages package:

npm install gh-pages --save-dev

3. Configure package.json

Modify your package.json file to include the homepage URL and deployment scripts.

Step 1: Add homepage field

Replace your-username and your-repository with your actual GitHub username and
repository name.

"homepage": "https://your-username.github.io/your-repository"

Step 2: Add Deployment Scripts

Modify the "scripts" section by adding the following lines:

"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
}

• predeploy → Builds the project before deployment.


• deploy → Uses gh-pages to publish the build folder.

4. Initialize Git and Push Code to GitHub

If your project is not already a Git repository, initialize it and push it to GitHub:

git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/your-username/your-repository.git
git push -u origin main

5. Deploy the React App

Run the deployment command:

npm run deploy

This will build the project and push the build folder to the gh-pages branch.

6. Enable GitHub Pages

1. Go to your repository on GitHub.


2. Navigate to Settings > Pages.
3. Under Branch, select gh-pages.
4. Click Save.

7. Access Your Deployed Site

After a few minutes, your site will be live at:

https://your-username.github.io/your-repository

8. Updating the Deployed App

When you make changes to your React app, redeploy it by running:


npm run deploy

This will update the live version on GitHub Pages.

Conclusion

GitHub Pages provides a free and easy way to host React apps.
gh-pages automates the deployment process.
Any updates can be pushed and redeployed with npm run deploy.

Would you like a guide on deploying with Netlify or Vercel as well?

You might also like