ReactJS: Practice Set 6

This set is about practicing useEffect and useState hook in React.

Rahul Kumar
14 min readMar 12, 2024

Q 1. Create a React component that calls the product api and has the same number of buttons as the items in product. On Click of each button show the details of that card only. Example: In the below API we have three products and three buttons.

Output:

fakeFetch has been provided:

fakeFetch7.jsx:

export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/products") {
resolve({
status: 200,
message: "Success",
data: {
products: [
{
name: "Shoes",
price: 3000,
desc: "lorem ipsum dolor sit amit",
src: "https://picsum.photos/200/200",
},
{
name: "Tshirt",
price: 500,
inStock: false,
desc: "lorem ipsum dolor sit amit",
src: "https://picsum.photos/201/201",
},
{
name: "Trekking Bag",
price: 2000,
inStock: true,
desc: "lorem ipsum dolor sit amit",
src: "https://picsum.photos/205/205",
},
],
},
});
} else {
reject({
status: 404,
message: "Items list not found.",
});
}
}, 2000);
});
};

Solution:

Component.jsx

import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch7";

const ProductsCard = () => {
const [products, setProducts] = useState();
const [selectedProductIndex, setSelectedProductIndex] = useState(null);

const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/products");

const { status, data } = res;
if (status === 200) {
setProducts(data.products);
//console.log(data,products);
}
} catch (e) {
console.log(e);
}
};

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

const handleClick = (index) =>{
setSelectedProductIndex(index);
}

return products ? (
<div>
{products.map((product, index) => {
return (
<button
key={index}
onClick={() => {
handleClick(index+1);
}}
>
show {product.name}
</button>
);
})}

<div>
{selectedProductIndex && (
<div>
<h2>Selected Product Details</h2>
{products.find((product ,index) => index+1 === selectedProductIndex) && (
<div>
<img src={products.find((product ,index) => index+1 === selectedProductIndex).src}></img>
<h1>Name: {products.find((product ,index) => index+1 === selectedProductIndex).name}</h1>
<h2>Price: {products.find((product, index) => index+1 === selectedProductIndex).price}</h2>
<h3>Description: {products.find((product ,index) => index+1 === selectedProductIndex).desc}</h3>
</div>
)}
</div>
)}
</div>

</div>
) : (
""
);
};

export default ProductsCard;

App.jsx

import "./App.css";
import React from "react";
import ProductsCard from "./practiceset6/ProductsCard";

const App = () => {
return <ProductsCard />;
};

export default App;

Q 2. Create a React component that calls the todo api and display the todos in an unordered list and show the todos as a list. The todo should display a heading with a little description of what that todo is about. Under that, it should display all the tasks to be done as a list.

Output:

fakeFetch has been provided:

fakeFetch8.jsx:

export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/todos") {
resolve({
status: 200,
message: "Success",
data: {
todos: [
{
title: "Go Outside",
desc: "Get some fresh air",
todos: ["shopping", "cricket", "walking"],
},
{
title: "Let's Work",
desc: "Deadline closes in 3 days",
todos: ["Feature update", "Team Meet", "Code Walkthrough"],
},
{
title: "Home Work",
desc: "To be done on priority",
todos: ["Fix tap", "Wedding function"],
},
],
},
});
} else {
reject({
status: 404,
message: "Todo list not found.",
});
}
}, 2000);
});
};

Solution:

Component.jsx

import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch8";

const TodosGroup = () => {
const [todosData, setTodosData] = useState();

const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/todos");

const { status, data } = res;
if (status === 200) {
setTodosData(data.todos);
}
} catch (e) {
console.log(e);
}
};

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

return todosData ? (
<div>
{todosData.map(({ title, desc, todos }, index) => {
return (
<div key={index} style={{borderBottom: "2px solid gray"}}>
<h1>
{title} : {desc}
</h1>
<ol>
{todos.map((todo) => (
<li>{todo}</li>
))}
</ol>
</div>
);
})}
</div>
) : (
" Loading..."
);
};

export default TodosGroup;

App.jsx

import "./App.css";
import React from "react";
import TodosGroup from "./practiceset6/TodosGroup";


const App = () => {
return <TodosGroup />;
};

export default App;

Q 3. Create a React component that calls the habit tracker api when the page is loaded completely and display the habits with the total days they were followed and days skipped in between.

Output:

fakeFetch has been provided:

fakeFetch9.jsx:

export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/habits") {
resolve({
status: 200,
message: "Success",
data: {
habits: [
{
title: "Drinking enough water",
desc: "Aim to drink 5-6L of water each day to stay hydrated",
daysFollowed: 7,
daysSkipped: 3,
},
{
title: "Exercise",
desc: "Track your workouts and aim to exercise a certain number of days per",
daysFollowed: 10,
daysSkipped: 4,
},
{
title: "Meditation",
desc: "Track your daily meditation practice and try to increase the length",
daysFollowed: 30,
daysSkipped: 7,
},
{
title: "Gratitude",
desc: "Write down something you are grateful for each day",
daysFollowed: 11,
daysSkipped: 5,
},
{
title: "Saving Money",
desc: "Track your expenses and set a goal to save a certain amount of money",
daysFollowed: 40,
daysSkipped: 15,
},
],
},
});
} else {
reject({
status: 404,
message: "Habits not found.",
});
}
}, 2000);
});
};

Solution:

Component.jsx

import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch9";

const HabitTracker = () => {
const [habitData, setHabitData] = useState();

const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/habits");

const { status, data } = res;
if (status === 200) {
setHabitData(data.habits);
console.log(data.habits);
}
} catch (e) {
console.log(e);
}
};

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

return habitData ? (
<div>
<h1>Habit Tracker</h1>
<ul>
{habitData.map(({ title, desc, daysFollowed, daysSkipped }, index) => {
return (
<li key={index} style={{borderBottom: "2px solid gray"}}>
<p>
<b style={{ fontSize: "20px" }}>{title}:</b> <br /> {desc}
</p>
<p>
<b>Days Followed:</b> {daysFollowed} <br />
<b>Days Skipped:</b> {daysSkipped}
</p>
</li>
);
})}
</ul>
</div>
) : (
"Loading"
);
};

export default HabitTracker;

App.jsx

import "./App.css";
import React from "react";

import HabitTracker from "./practiceset6/HabitTracker";


const App = () => {
return <HabitTracker />;
};

export default App;

Q 4. Create a React component that calls the video library api when the page is loaded completely and display all the videos on the screen. And on click of delete button, delete the first video in the list.

Output:

fakeFetch has been provided:

fakeFetch10.jsx:

export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/videos") {
resolve({
status: 200,
message: "Success",
data: {
videos: [
{
title: "The Power of Habit",
thumbnail: "https://picsum.photos/200/130",
views: 1000000,
likes: 50000,
},
{
title: "How to Code in JavaScript",
thumbnail: "https://picsum.photos/200/135",
views: 500000,
likes: 25000,
},
{
title: "10 Minute Yoga for Beginners",
thumbnail: "https://picsum.photos/200/131",
views: 250000,
likes: 15000,
},
{
title: "Introduction to Machine Learning",
thumbnail: "https://picsum.photos/200/132",
views: 100000,
likes: 10000,
},
{
title: "The Science of Cooking",
thumbnail: "https://picsum.photos/200/133",
views: 75000,
likes: 5000,
},
{
title: "The Art of Public Speaking",
thumbnail: "https://picsum.photos/200/134",
views: 50000,
likes: 2500,
},
],
},
});
} else {
reject({
status: 404,
message: "Videos not found.",
});
}
}, 2000);
});
};

Solution:

Component.jsx

import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch10";

const VideoLibrary = () => {
const [videoData, setVideoData] = useState();

const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/videos");

const { status, data } = res;
if (status === 200) {
setVideoData(data.videos);
console.log(data.videos);
}
} catch (e) {
console.log(e);
}
};

useEffect(() => {
fetchData();
}, []);
return videoData ? (
<div> <h1>Playlist</h1>
<div style={{display: "flex", flexWrap:"wrap", gap: "20px"}}>

{videoData.map(({ title, thumbnail, views, likes }, index) => {
return (
<div key={index} >
<img src={thumbnail} alt="" />
<p>
{" "}
<b>{title}</b>
<br />
<b>Views:</b>
{views}
<br />
<b>Likes:</b> {likes}
</p>
</div>
);
})}
</div>
<button onClick={()=> setVideoData(videoData.filter((data, index) => index !== 0))}>Delete</button>
</div>
) : (
<>Loading...</>
);
};

export default VideoLibrary;

App.jsx

import "./App.css";
import React from "react";

import VideoLibrary from "./practiceset6/VideoLibrary";


const App = () => {
return <VideoLibrary />;
};

export default App;

Q 5. Create a react component that calls the social media api when the page is loaded completely and display all the posts on the screen. And on click of show bakery button, show only the posts with category as bakery.

fakeFetch has been provided:

fakeFetch11.jsx:

export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/posts") {
resolve({
status: 200,
message: "Success",
data: {
posts: [
{
caption: "Delicious chocolate cake recipe",
src: "https://picsum.photos/300/301",
views: 1000,
likes: 100,
category: "Bakery",
},
{
caption: "5-minute breakfast ideas",
src: "https://picsum.photos/300/300",
views: 500,
likes: 50,
category: "Food",
},
{
caption: "The best bread recipe you'll ever taste",
src: "https://picsum.photos/300/302",
views: 2000,
likes: 200,
category: "Bakery",
},
{
caption: "10 DIY home decor ideas",
src: "https://picsum.photos/300/303",
views: 100,
likes: 10,
category: "DIY",
},
{
caption: "Healthy snacks for work",
src: "https://picsum.photos/300/304",
views: 300,
likes: 30,
category: "Food",
},
{
caption: "How to make sourdough bread at home",
src: "https://picsum.photos/300/305",
views: 1500,
likes: 150,
category: "Bakery",
},
],
},
});
} else {
reject({
status: 404,
message: "Post not found.",
});
}
}, 2000);
});
};

Solution:

Component.jsx

import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch11";

const SocialMediaPost = () => {
const [postData, setPostData] = useState();

const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/posts");

const { status, data } = res;
if (status === 200) {
setPostData(data.posts);
console.log(data.posts);
}
} catch (e) {
console.log(e);
}
};

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

return postData ? (
<div>
{" "}
<h1>Post</h1>
<div style={{ display: "flex", flexWrap: "wrap", gap: "20px" }}>
{postData.map(({ caption, src, views, likes }, index) => {
return (
<div key={index}>
<img src={src} alt="" />
<p>
{" "}
<b>{caption}</b>
<br />
<b>Views:</b>
{views}
<br />
<b>Likes:</b> {likes}
</p>
</div>
);
})}
</div>
<button
onClick={() => {
setPostData(postData.filter(({ category }) => category === "Bakery"));
}}
>
Show bakery
</button>
</div>
) : (
<>Loading...</>
);
};

export default SocialMediaPost;

App.jsx

import "./App.css";
import React from "react";

import SocialMediaPost from "./practiceset6/SocialMediaPost";


const App = () => {
return <SocialMediaPost />;
};

export default App;

Q6. Create a React component that calls the habit tracker api and display only the habits which are unarchived with headingUnarchived”.

Create a show archive button and on click of show archive button show the archive habits and hide the unarchives. Change the heading of the page to “Archived” when the button is clicked.

Output:

fakeFetch has been provided:

fakeFetch12.jsx:

export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/habits") {
resolve({
status: 200,
message: "Success",
data: {
habits: [
{
title: "Drinking enough water",
desc: "Aim to drink 5-6L of water each day to stay hydrated",
daysFollowed: 7,
daysSkipped: 3,
archived: false,
},
{
title: "Exercise",
desc: "Track your workouts and aim to exercise a certain number of days per",
daysFollowed: 10,
daysSkipped: 4,
archived: true,
},
{
title: "Meditation",
desc: "Track your daily meditation practice and try to increase the length",
daysFollowed: 30,
daysSkipped: 7,
archived: true,
},
{
title: "Gratitude",
desc: "Write down something you are grateful for each day",
daysFollowed: 11,
daysSkipped: 5,
archived: false,
},
{
title: "Saving Money",
desc: "Track your expenses and set a goal to save a certain amount of money",
daysFollowed: 40,
daysSkipped: 15,
archived: false,
},
],
},
});
} else {
reject({
status: 404,
message: "Habits not found.",
});
}
}, 2000);
});
};

Solution:

Component.jsx

import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch12";

const ArchieveAndUnArchieve = () => {
const [habitData, setHabitData] = useState();
const [heading, setHeading] = useState("UnArchieved");
const [data,setData] = useState();

const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/habits");
const { status, data } = res;
if (status === 200) {
setHabitData(data.habits);
setData(data.habits?.filter((habit) => !habit.archived));
}
} catch (e) {
console.error("Error fetching habits:", e);
// Handle errors here (display message, retry, etc.)
}
};

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



return habitData ? (
<div>
<h1>{heading}</h1>
<ul>
{data.map(({ title, desc, daysFollowed, daysSkipped }, index) => (
<li key={index} style={{ borderBottom: "2px solid gray" }}>
<p>
<b style={{ fontSize: "20px" }}>{title}:</b> <br /> {desc}
</p>
<p>
<b>Days Followed:</b> {daysFollowed} <br />
<b>Days Skipped:</b> {daysSkipped}
</p>
</li>
))}
</ul>
<button onClick={()=>{
setHeading("Archived");
setData(habitData.filter((habit) => habit.archived))
}}>Show archived</button>
</div>
) : (
<>Loading...</>
);
};

export default ArchieveAndUnArchieve;

App.jsx

import "./App.css";
import React from "react";

import ArchieveAndUnArchieve from "./practiceset6/ArchieveAndUnArchieve";


const App = () => {
return <ArchieveAndUnArchieve />;
};

export default App;

Q7. Create a React component that calls the projects api and list all the projects when the page loads with titles and description. Create buttons saying “Show Details” for each project.

On click of the button show title, description, technologies, completed of that project only.

fakeFetch has been provided:

fakeFetch13.jsx:

export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/projects") {
resolve({
status: 200,
message: "Success",
data: {
projects: [
{
title: "E-commerce Website",
description:
"A fully functional e-commerce website with shopping cart and checkout fun",
technologies: ["React", "Node.js", "Express", "MongoDB"],
completed: false,
},
{
title: "Weather App",
description:
"A web application that displays the current weather and forecast",
technologies: ["React", "Node.js", "OpenWeatherMap API"],
completed: true,
},
{
title: "Task Manager",
description:
"A web application that allows users to create, manage and track tasks.",
technologies: ["Vue.js", "Firebase"],
completed: false,
},
{
title: "Blog Website",
description:
"A blog website that allows users to create, read, update and delete blog",
technologies: ["React JS", "MongoDB"],
completed: true,
},
{
title: "Mobile Game",
description:
"A mobile game developed for iOS and Android platforms.",
technologies: ["Unity", "C#"],
completed: false,
},
],
},
});
} else {
reject({
status: 404,
message: "Projects not found.",
});
}
}, 2000);
});
};

Solution:

Component.jsx

import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch13";

const ProjectsCard = () => {
const [projectsData, setProjectsData] = useState();
const [showDetails, setShowDetails] = useState(null);

const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/projects");

const { status, data } = res;
if (status === 200) {
setProjectsData(data.projects);
console.log(data.projects);
}
} catch (e) {
console.log(e);
}
};

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

return projectsData ? (
<div>
<h1>Projects</h1>
{projectsData.map((project, index) => {
const { title, description } = project;
return (
<div key={index}>
<p>
<b>Name:</b>
{title} <br />
<b>Description:</b>
{description}
</p>
<button onClick={() => setShowDetails(project)}>
Show Details
</button>
</div>
);
})}

<div>
{showDetails && (
<div>
<div>
<h1>Project Details</h1>
<p>
<b>Name:</b>
{showDetails.title} <br />
<b>Description:</b>
{showDetails.description}
<br />
<b>Technologies: </b> {showDetails.technologies}
<br />
<b>Completed: </b> {showDetails.completed.toString()}
</p>
</div>

{console.log(showDetails)}
</div>
)}
</div>
</div>
) : (
"Loading..."
);
};

export default ProjectsCard;

App.jsx

import "./App.css";
import React from "react";

import ProjectsCard from "./practiceset6/ProjectsCard";


const App = () => {
return <ProjectsCard />;
};

export default App;

Q 8. Create a React component that calls the userProfile api and list the details of the user when the page loads. Create a button saying Update name and on click of that button, change the name of the user.

Output:

1st on Rendering:

2nd after clicking on update name button:

fakeFetch has been provided:

fakeFetch14.jsx:

export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/profile") {
resolve({
status: 200,
message: "Success",
data: {
profiles: {
name: "John",
age: 30,
gender: "male",
email: "john@example.com",
occupation: "Software Engineer",
},
},
});
} else {
reject({
status: 404,
message: "User Profile not found.",
});
}
}, 2000);
});
};

Solution:

Component.jsx

import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch14";

const UserProfile = () => {
const [profilesData, setProfilesData] = useState();

const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/profile");

const { status, data } = res;
if (status === 200) {
setProfilesData(data.profiles);
console.log(data.profiles);
}
} catch (e) {
console.log(e);
}
};

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

return profilesData ? (
<div>
<h1>Profiles</h1>
<p>
<b>Name: </b> {profilesData.name}
<br />
<b>Email: </b> {profilesData.email}
<br />
<b>Age:</b> {profilesData.age}
<br />
<b>Gender: </b>
{profilesData.age}
<br />
<b>Occupation: </b> {profilesData.occupation}
</p>
<button
onClick={() => {
setProfilesData({ ...profilesData, name: "Rahul" });
}}
>
Update name
</button>
</div>
) : (
"Loading..."
);
};

export default UserProfile;

App.jsx

import "./App.css";
import React from "react";

import UserProfile from "./practiceset6/UserProfile";


const App = () => {
return <UserProfile />;
};

export default App;

Q9. Create a React component that calls the video api and display all the details of the video on the screen. And on click of add label button, add a label property to the object and display the details on the screen

Output:

fakeFetch has been provided:

fakeFetch15.jsx:

export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/getvideo") {
resolve({
status: 200,
message: "Success",
data: {
videos: {
title: "The Power of Habit",
thumbnail: "https://picsum.photos/250/130",
views: 1000000,
likes: 50000,
},
},
});
} else {
reject({
status: 404,
message: "Video not found.",
});
}
}, 2000);
});
};

Solution:

VideoLabel.jsx

import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch15";

const VideoLabel = () => {
const [videoData, setVideoData] = useState();
const [label, setLabel] = useState();

const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/getvideo");
const { status, data } = res;

if (status === 200) {
setVideoData(data.videos);
console.log(data.videos);
}
} catch (e) {
console.error("Error fetching profile data:", e);
}
};

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


return (
videoData ? <div>
<img src={videoData.thumbnail} alt="" />
<p>
<b>{videoData.title}</b>
<br />
<b>Views: </b>{videoData.views}
<br />
<b>Likes:</b>{videoData.likes}
<br />
{label && <span><b>Label:</b> {label}</span>}
</p>

<button onClick={()=>{setLabel("Self Motivational")}}>Add a Label</button>
</div> : "Loading..."
)
};

export default VideoLabel;

App.jsx

import "./App.css";
import React from "react";

import VideoLabel from "./practiceset6/VideoLabel";

const App = () => {
return <VideoLabel />
};

export default App;

Q 10. Create a React component that calls the socialMedia profile api and when the page is loaded show details of the user and a button follow along with the name of the user on the button. On click of that increase the followers count by one and disable the button.

Output:

fakeFetch has been provided:

fakeFetch16.jsx:

export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/profile") {
resolve({
status: 200,
message: "Success",
data: {
profile: {
name: "John",
age: 30,
gender: "male",
email: "john@example.com",
occupation: "Software Engineer",
followers: 450,
followedBy: 400,
},
},
});
} else {
reject({
status: 404,
message: "Profile not found.",
});
}
}, 2000);
});
};

Solution:

Component.jsx

import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch16";

const UserProfileFollower = () => {
const [profilesData, setProfilesData] = useState();
const [disable, setDisable] = useState(false);

const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/profile");
const { status, data } = res;
console.log(status, data);
if (status === 200) {
setProfilesData(data.profile);
console.log(data.profiles);
}
} catch (e) {
console.error("Error fetching profile data:", e);
}
};

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

const handleFollow = () => {
setProfilesData((prevProfiles) => ({
...prevProfiles,
followers: prevProfiles.followers + 1,
}));
setDisable(true);
};

return profilesData ? (
<div>
<h1>{profilesData.name}</h1>
<p>
<b>Views: </b> {profilesData.views}
<br />
<b>Email: </b> {profilesData.email}
<br />
<b>Age:</b> {profilesData.age}
<br />
<b>Gender: </b> {profilesData.age}
<br />
<b>Occupation: </b> {profilesData.occupation}
<br />
<b>Followers: </b> {profilesData.followers}
<br />
<b>Followed By: </b> {profilesData.followedBy}
</p>

<button onClick={handleFollow} disabled={disable}>
Follow {profilesData.name}
</button>
</div>
) : (
"Loading..."
);
};

export default UserProfileFollower;

App.jsx

import "./App.css";
import React from "react";

import UserProfileFollower from "./practiceset6/UserProfileFollower";


const App = () => {
return <UserProfileFollower />;
};

export default App;

Thanks…

--

--