ReactJS : Practice Set 7
Q 1. Create a React component that fetches weather data from an API endpoint using useEffect hook and displays the current temperature, humidity, and wind speed on the screen using the useState hook.
Add a button which toggles between Celsius and Fahrenheit units for the temperature.
Expected Output:
On Rendering:
On clicking the button
fakeFetch has been provided:
fakeFetch17.jsx:
export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/weather") {
resolve({
status: 200,
message: "Success",
data: {
temperature: 21,
humidity: 50,
windSpeed: 10,
},
});
} else {
reject({
status: 404,
message: "Weather data not found.",
});
}
}, 2000);
});
};
Solution:
Component.jsx
import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch17";
const Weather = () => {
const [data, setData] = useState();
const [toggleoCtooF, setToggleoCtooF] = useState(false);
const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/weather");
// console.log(res.data);
const { status, data } = res;
if (status === 200) {
setData(data);
}
} catch (e) {
console.log(e);
}
};
useEffect(() => {
fetchData();
}, []);
return data ? (
<div>
<h1>Weather</h1>
<p>
<b>Temperature: </b>
{toggleoCtooF ? (
<>
{data.temperature} <sup>o</sup>C
</>
) : (
<>
{Math.round((data.temperature * 9) / 5 + 32)} <sup>o</sup>F
</>
)}
</p>
<p>
<b>Humidity: </b>
{data.humidity} %
</p>
<p>
<b>Wind Speed: </b>
{data.windSpeed} km/hr
</p>
<button onClick={() => setToggleoCtooF(!toggleoCtooF)}>
Switch to {toggleoCtooF ? "Fahrenheit" : "Celcius"}
</button>
</div>
) : (
<>Loading...</>
);
};
export default Weather;
App.jsx
import "./App.css";
import React from "react";
import Weather from "./practiceset7/Weather";
const App = () => {
return <Weather />
};
export default App;
Q 2. Create a React component that fetches user data from an API endpoint using useEffect hook and displays the user’s name, email, and phone number on the screen using the useState hook.
Add a button which toggles the display of the user’s address (street, suite, city, zipcode).
E x p e c t e d O u t p u t:
On clicking the button:
fakeFetch has been provided:
fakeFetch18.jsx:
export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/user") {
resolve({
status: 200,
message: "Success",
data: {
name: "John Doe",
email: "john.doe@example.com",
phone: "+1 555-555-5555",
address: {
street: "123 Main St",
suite: "Suite 456",
city: "Anytown",
zipcode: "12345",
},
},
});
} else {
reject({
status: 404,
message: "User not found.",
});
}
}, 2000);
});
};
Solution:
Component.jsx
import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch18";
const UserAddressToggle = () => {
const [userData, setUserData] = useState();
const[showAddress, setShowAddress] = useState(false);
const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/user");
const { status, data } = res;
if (status === 200) {
setUserData(data);
}
} catch (e) {
console.log(e);
}
};
useEffect(() => {
fetchData();
}, []);
return userData ? <div>
<h1>User</h1>
<p>Name: {userData.name}</p>
<p>Email: {userData.email}</p>
<p>Phone: {userData.phone}</p>
<button onClick={()=>setShowAddress(!showAddress)}>{showAddress?"Hide Address": "Show Address"}</button>
{showAddress && <div>
<p> {userData.address.street}</p>
<p> {userData.address.suite}</p>
<p> {userData.address.city}</p>
<p>{userData.address.zipcode}</p>
</div>}
</div> : "Loading";
};
export default UserAddressToggle;
App.jsx
import "./App.css";
import React from "react";
import UserAddressToggle from "./practiceset7/UserAddressToggle";
const App = () => {
return <UserAddressToggle />;
};
export default App;
Q3. Create a React component that fetches a list of movies from an API endpoint using useEffect hook and displays the title, year, and rating of each movie on the screen using the useState hook.
Add a dropdown which filters the movies by year. You can keep 5 dropdown values : 2005 to 2010.
E x p e c t e d O u t p u t:
On typing the year, it will filter:
fakeFetch has been provided:
fakeFetch.jsx:
export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/movies") {
resolve({
status: 200,
message: "Success",
data: [
{ title: "The Dark Knight", year: 2008, rating: 9.0 },
{ title: "Inception", year: 2009, rating: 8.8 },
{ title: "Interstellar", year: 2010, rating: 8.6 },
{ title: "Tenet", year: 2009, rating: 7.5 },
{ title: "Real Steal", year: 2007, rating: 7.5 },
],
});
} else {
reject({
status: 404,
message: "Movies list not found.",
});
}
}, 2000);
});
};
Solution:
Component.jsx
import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch19";
const MoviesList = () => {
const [moviesData, setMoviesData] = useState();
const [selectedYear, setSelectedYear] = useState();
const handleYearChange = (e) => {
setSelectedYear(e.target.value);
};
const filteredMovies = selectedYear && moviesData ? moviesData.filter(({year})=>year==selectedYear) : moviesData;
const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/movies");
const { status, data } = res;
if (status === 200) {
setMoviesData(data);
}
} catch (e) {
console.error(e); // Use console.error for errors
}
};
useEffect(() => {
fetchData();
}, []);
return moviesData ? (
<div>
<h1>Movies</h1>
<select onChange={handleYearChange}>
<option value="">All Years</option>
<option value="2005">2005</option>
<option value="2006">2006</option>
<option value="2007">2007</option>
<option value="2008">2008</option>
<option value="2009">2009</option>
<option value="2010">2010</option>
</select>
<div>
{
filteredMovies.length == 0 ? "No Data Found!!!" :
<ul>
{filteredMovies.map((movie, index) => (
<li key={index}>
<b>{movie.title}</b>
<br />
Release: {movie.year}
<br />
Rating: {movie.rating}
</li>
))}
</ul>
}
</div>
</div>
) : (
"Loading Movies List..."
);
};
export default MoviesList;
App.jsx
import "./App.css";
import React from "react";
import MoviesList from "./practiceset7/MoviesList";
const App = () => {
return <MoviesList />;
};
export default App;
Q4. Create a React component that fetches a list of users from an API endpoint using useEffect hook and displays the name, email, and website of each user on the screen using the useState hook.
Add a dropdown which filters the users by company name.
E x p e c t e d O u t p u t:
export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/users") {
resolve({
status: 200,
message: "Success",
data: [
{
name: "John Doe",
email: "john@example.com",
website: "example.com",
company: "ABC Inc",
},
{
name: "Jane Doe",
email: "jane@example.com",
website: "example.com",
company: "XYZ Corp",
},
{
name: "Bob Smith",
email: "bob@example.com",
website: "example.com",
company: "ABC Inc",
},
{
name: "Alice Brown",
email: "alice@example.com",
website: "example.com",
company: "ACME Corp",
},
{
name: "Charlie Green",
email: "charlie@example.com",
website: "example.com",
company: "XYZ Corp",
},
],
});
} else {
reject({
status: 404,
message: "Users list not found.",
});
}
}, 2000);
});
};
Solution:
Component.jsx
import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch20";
const UserCompanyDropDown = () => {
const [userData, setUserData] = useState();
const [filteredUserByCompany, setFilteredUserByCompany] = useState();
const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/users");
const { status, data } = res;
if (status === 200) {
setUserData(data);
setFilteredUserByCompany(data);
}
} catch (e) {
console.error(e);
}
};
useEffect(() => {
fetchData();
}, []);
const uniqueCompanies = userData?.reduce(
(acc, { company }) => {
// Check if company already exists in the accumulator
if (!acc.includes(company)) {
// If not found, add it to the accumulator
return [...acc, company];
}
// If found, return the accumulator as is (no duplicates added)
return acc;
},
["All"]
);
const handleChange = (e) => {
if (e.target.value === "All") {
setFilteredUserByCompany(userData); // Set all users if "All" selected
} else {
// Filter users by company when a specific company is selected
setFilteredUserByCompany(userData.filter(({ company }) => company === e.target.value));
}
};
return userData ? (
<div>
<h1>User</h1>
<select onChange={handleChange}> {/* Set default value to first company for visual cue */}
{uniqueCompanies.map((comp, index) => (
<option key={index} value={comp}>
{comp}
</option>
))}
</select>
<ul>
{filteredUserByCompany.map(({ name, email, website, company }, index) => (
<li key={index}>
<p>{name}</p>
<p>{email}</p>
<p>{website}</p>
<p>{company}</p>
</li>
))}
</ul>
</div>
) : (
"Loading"
);
};
export default UserCompanyDropDown;
App.jsx
import "./App.css";
import React from "react";
import UserCompanyDropDown from "./practiceset7/UserCompanyDropDown";
const App = () => {
return <UserCompanyDropDown />;
};
export default App;
Q5. Create a React component that displays a random quote from an API using the useEffect and useState hooks. The component should fetch a new quote when the user clicks a button.
fakeFetch21.jsx
export const fakeFetch = () => {
const quotes = [
{
content: "Be yourself; everyone else is already taken.",
author: "Oscar Wilde",
},
{
content:
"Two things are infinite: the universe and human stupidity; and I'm not sure about Second One",
author: "Albert Einstein",
},
{
content: "So many books, so little time.",
author: "Frank Zappa",
},
{
content: "A room without books is like a body without a soul.",
author: "Marcus Tullius Cicero",
},
{
content:
"In three words I can sum up everything I've learned about life: it goes on.",
author: "Robert Frost",
},
];
return new Promise((resolve) => {
setTimeout(() => {
const randomQuote = quotes[Math.floor(Math.random() * quotes.length)];
resolve(randomQuote);
}, 1000);
});
};
Output:
On Clicking on New Quote:
Solution:
Component.jsx
import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch21";
const RandomQuotesGenerator = () => {
const [quotes, setQuotes] = useState();
const fetchQuotes = async () => {
const res = await fakeFetch();
setQuotes(res);
// console.log(res);
};
useEffect(() => {
fetchQuotes();
}, []);
return quotes ? (
<div>
<p>
<b>"{quotes.content}</b>
</p>
<p>-{quotes.author}</p>
<button onClick={fetchQuotes}>New Quote</button>
</div>
) : (
"Loading Quotes... "
);
};
export default RandomQuotesGenerator;
App.jsx
import "./App.css";
import React from "react";
import UserCompanyDropDown from "./practiceset7/UserCompanyDropDown";
import RandomQuotesGenerator from "./practiceset7/RandomQuotesGenerator";
const App = () => {
return <RandomQuotesGenerator />;
};
export default App;
Q 6. Create a React component that fetches a list of movies from an API endpoint using useEffect hook and displays the title, year, and genre of each movie on the screen using the useState hook.
Add a dropdown which filters the movies by genre.
Expected Output:
On typing the genre, it will filter out:
fakeFetch22.jsx
export const fakeFetch = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "https://example.com/api/movies") {
resolve({
status: 200,
message: "Success",
data: [
{
title: "The Godfather",
year: 1972,
genre: "Crime",
},
{
title: "The Shawshank Redemption",
year: 1994,
genre: "Drama",
},
{
title: "The Dark Knight",
year: 2008,
genre: "Action",
},
{
title: "Forrest Gump",
year: 1994,
genre: "Comedy",
},
{
title: "The Matrix",
year: 1999,
genre: "Science Fiction",
},
{
title: "Jurassic Park",
year: 1993,
genre: "Science Fiction",
},
{
title: "Star Wars: Episode IV - A New Hope",
year: 1977,
genre: "Science Fiction",
},
{
title: "The Terminator",
year: 1984,
genre: "Action",
},
{
title: "Die Hard",
year: 1988,
genre: "Action",
},
{
title: "Pulp Fiction",
year: 1994,
genre: "Crime",
},
],
});
} else {
reject({
status: 404,
message: "Movies list not found.",
});
}
}, 2000);
});
};
Solution:
Component.jsx
import React, { useEffect, useState } from "react";
import { fakeFetch } from "../api/fakeFetch22";
const MoviesListFilterByGenreDropdown = () => {
const [movies, setMovies] = useState();
const [filteredMovies, setFilteredMovies] = useState();
const fetchMovies = async () => {
try {
const res = await fakeFetch("https://example.com/api/movies");
const { status, data } = res;
if (status === 200) {
setMovies(data);
setFilteredMovies(data);
console.log(data);
}
} catch (e) {
console.error(e);
}
};
useEffect(() => {
fetchMovies();
}, []);
const uniqueMoviesByGenre = movies?.reduce(
(acc, { genre }) => {
if (!acc.includes(genre)) {
return [...acc, genre];
}
return [...acc];
},
["All"]
);
// console.log(uniqueMoviesByGenre)
const handleChange = (e) => {
// console.log(e.target.value);
if (e.target.value === "All") {
setFilteredMovies(movies);
} else {
setFilteredMovies(movies.filter(({ genre }) => genre === e.target.value));
}
};
return movies ? (
<div>
<h1>Movies</h1>
<select onChange={handleChange}>
{uniqueMoviesByGenre.map((genre) => (
<option value={genre}>{genre}</option>
))}
</select>
<ul>
{filteredMovies.map(({ title, year, genre }, index) => (
<li key={index}>
<p>
<b>{title}</b>
</p>
<p>{year}</p>
<p>{genre}</p>
</li>
))}
</ul>
</div>
) : (
"Loading"
);
};
export default MoviesListFilterByGenreDropdown;
App.jsx
import "./App.css";
import React from "react";
import MoviesListFilterByGenreDropdown from "./practiceset7/MoviesListFilterByGenreDropdown";
const App = () => {
return <MoviesListFilterByGenreDropdown />;
};
export default App;
Q 7. Create a React component that fetches a list of products from an e-commerce API endpoint using useEffect hook and displays the product name, description, price, and quantity on the screen using the useState hook.
Add a button which allows the user to sort the products by price (lowest to highest).
fakeFetch23.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: "Product 1",
description: "This is the first product",
price: 25.99,
quantity: 10,
},
{
name: "Product 2",
description: "This is the second product",
price: 19.99,
quantity: 15,
},
{
name: "Product 3",
description: "This is the third product",
price: 35.5,
quantity: 5,
},
{
name: "Product 4",
description: "This is the fourth product",
price: 49.99,
quantity: 20,
},
],
},
});
} else {
reject({
status: 404,
message: "Product list not found.",
});
}
}, 2000);
});
};
Expected Output:
After Clicking on button “Sort by price” :
Solution:
Component.jsx
import React,{useState, useEffect} from "react";
import { fakeFetch } from "../api/fakeFetch23";
const ProductsBySort = () => {
const [products, setProducts] = useState();
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 = () => {
products.sort((a, b) => a.price - b.price); // Sort directly on existing products array
setProducts([...products]); // Trigger re-render with sorted products (state update)
};
return products ? (
<div>
<button onClick={handleClick}>Sort by price</button>
<ul>
{products.map(({ name, description, price, quantity }, index) => {
return (
<li key={index}>
<h1>{name}</h1>
<p>{description}</p>
<p>Rs.{price}</p>
<p>Quantity: {quantity}</p>
</li>
);
})}
</ul>
</div>
) : (
"Loading..."
);
};
export default ProductsBySort;
App.jsx
import "./App.css";
import React from "react";
import ProductsBySort from "./practiceset7/ProductsBySort";
const App = () => {
return <ProductsBySort />;
};
export default App;
Q. 8. Adding on to the previous question, There should be three buttons for this purpose: “Low to High”, “High to Low”, and “Reset”.
- When the user clicks on “Low to High”, the products should be sorted by price in ascending order.
- When the user clicks on “High to Low”, the products should be sorted by price in descending order.
- When the user clicks on “Reset”, the products should be displayed in their original order.
Expected Output:
On click Low to High:
On click High to Low:
On click the Reset button:
Solution:
Component.jsx
import React,{useState, useEffect} from "react";
import { fakeFetch } from "../api/fakeFetch23";
const ProductsBySort = () => {
const [products, setProducts] = useState();
const [sortedProducts, setSortedProducts] = useState();
const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/products");
const { status, data } = res;
if (status === 200) {
setProducts(data.products);
setSortedProducts(data.products);
console.log(data.products);
}
} catch (e) {
console.log(e);
}
};
useEffect(() => {
fetchData();
}, []);
const handleClick = () => {
sortedProducts.sort((a, b) => a.price - b.price);
setSortedProducts([...sortedProducts]);
};
const handleClick2 = () => {
sortedProducts.sort((a, b) => b.price - a.price);
setSortedProducts([...sortedProducts]);
};
const handleReset = () =>{
setSortedProducts([...products])
}
{
console.log(products)
}
return products ? (
<div>
<button onClick={handleClick}>Sort by price(Low to High)</button>
<button onClick={handleClick2}>Sort by price(High to Low)</button>
<button onClick={handleReset}>Reset</button>
<ul>
{sortedProducts.map(({ name, description, price, quantity }, index) => {
return (
<li key={index}>
<h1>{name}</h1>
<p>{description}</p>
<p>Rs.{price}</p>
<p>Quantity: {quantity}</p>
</li>
);
})}
</ul>
</div>
) : (
"Loading..."
);
};
export default ProductsBySort;
App.jsx
import "./App.css";
import React from "react";
import ProductsBySort from "./practiceset7/ProductsBySort";
const App = () => {
return <ProductsBySort />;
};
export default App;
Q9. Create a React component that uses the useEffect hook to fetch the product data from the API endpoint using the fakeFetch function provided below.
The component should use the useState hook to store the fetched data and a second state variable to store the sorted data. The sorted data should be sorted in descending order by rating.
fakeFetch24.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: "Color Pencils", price: 50, quantity: 40, rating: 4.5 },
{ name: "Sketchpens", price: 110, quantity: 20, rating: 3.8 },
{ name: "Eraser", price: 20, quantity: 20, rating: 4.2 },
{ name: "Sharpener", price: 22, quantity: 30, rating: 4.7 },
],
},
});
} else {
reject({
status: 404,
message: "Product list not found.",
});
}
}, 2000);
});
};
Expected Output:
Solution:
Component.jsx
import React, { useState, useEffect } from "react";
import { fakeFetch } from "../api/fakeFetch24";
const ProductsByRating = () => {
const [products, setProducts] = useState();
const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/products");
const { status, data } = res;
if (status === 200) {
setProducts(data.products.sort((a, b) => b.rating - a.rating));
}
} catch (e) {
console.log(e);
}
};
useEffect(() => {
fetchData();
}, []);
return products ? (
<div>
<h1>Products</h1>
<ul>
{products.map(
({ name, description, price, quantity, rating }, index) => {
return (
<li
key={index}
style={{
border: "2px solid gray",
margin: "10px",
listStyle: "none",
}}
>
<p style={{ display: "inline" }}>
{name}
<b style={{ display: "inline", margin: "200px" }}>
Rating:{rating}
</b>{" "}
</p>
<p>{description}</p>
<p>Rs.{price}</p>
<p>Quantity: {quantity}</p>
</li>
);
}
)}
</ul>
</div>
) : (
"Loading..."
);
};
export default ProductsByRating;
App.jsx
import "./App.css";
import React from "react";
import ProductsByRating from "./practiceset7/ProductsByRating";
const App = () => {
return <ProductsByRating />;
};
export default App;
Q10. Adding on to the previous question, Add a search bar to the component that allows users to filter the products by name.
The search bar should update the list of displayed products in real-time as the user types. The search functionality should be case-insensitive.
Expected Output:
fakeFetch25.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: "Color Pencils", price: 50, quantity: 40, rating: 4.5 },
{ name: "Sketchpens", price: 110, quantity: 20, rating: 3.8 },
{ name: "Eraser", price: 20, quantity: 20, rating: 4.2 },
{ name: "Sharpener", price: 22, quantity: 30, rating: 4.7 },
],
},
});
} else {
reject({
status: 404,
message: "Product list not found.",
});
}
}, 2000);
});
};
Solution:
Component.jsx
import React, { useState, useEffect } from "react";
import { fakeFetch } from "../api/fakeFetch24";
const ProductsSearch = () => {
const [products, setProducts] = useState();
const [filteredProducts, setFilteredProducts] = useState();
const fetchData = async () => {
try {
const res = await fakeFetch("https://example.com/api/products");
const { status, data } = res;
if (status === 200) {
setProducts(data.products);
setFilteredProducts(data.products);
}
} catch (e) {
console.log(e);
}
};
useEffect(() => {
fetchData();
}, []);
return products ? (
<div>
<h1>Products</h1>
<input type="text" name="search-products" onChange={(e)=>{
console.log(e.target.value)
setFilteredProducts(products.filter(({name})=> name.toLowerCase().includes(e.target.value.toLowerCase())))
}} />
<ul>
{filteredProducts.map(
({ name, description, price, quantity, rating }, index) => {
return (
<li
key={index}
style={{
border: "2px solid gray",
margin: "10px",
listStyle: "none",
}}
>
<p style={{ display: "inline" }}>
{name}
<b style={{ display: "inline", margin: "200px" }}>
Rating:{rating}
</b>{" "}
</p>
<p>{description}</p>
<p>Rs.{price}</p>
<p>Quantity: {quantity}</p>
</li>
);
}
)}
</ul>
</div>
) : (
"Loading..."
);
};
export default ProductsSearch;
App.jsx
import "./App.css";
import React from "react";
import ProductsSearch from "./practiceset7/ProductsSearch";
const App = () => {
return <ProductsSearch />;
};
export default App;