How to add spinner while loading data in react.js? - reactjs

I want to add spinner while loading data from database. For fetching data I am using react-hook. Here is my code ,how can I add spinner here?
import React from "react";
import { useNavigate } from "react-router-dom";
import useInventories from "../../../hooks/useInventories";
import Inventory from "../Inventory/Inventory";
const Inventories = () => {
const [inventories] = useInventories();
return (
<>
<div id="inventory" className="container mt-5 ">
<h2 className="text-center my-5 text-primary ">Inventory</h2>
<div className="row row-cols-1 row-cols-md-3 g-4 border-1 ">
{inventories.slice(0, 6).map((inventory) => (
<Inventory key={inventory._id} inventory={inventory}></Inventory>
))}
</div>
</div>
</>
);
};
export default Inventories;
It take a little bit time to load data from mongodb. So I want to add spinner loading before that.

You can do solution with useEffect. Basically initial loading is true and it becomes false when you have inventories data. I also see that you are using tailwind so you can set spinner icon animation directly with animate-spin
import React from "react";
import { useNavigate } from "react-router-dom";
import useInventories from "../../../hooks/useInventories";
import Inventory from "../Inventory/Inventory";
const Inventories = () => {
const [inventories] = useInventories();
const [loading, setLoading] = useState(true)
useEffect(() => {
if(inventories?.length > 0) {
setLoading(false)
}
}, [inventories])
return (
<>
{loading <SpinnerComponent/> }
{!loading
<div id="inventory" className="container mt-5 ">
<h2 className="text-center my-5 text-primary ">Inventory</h2>
<div className="row row-cols-1 row-cols-md-3 g-4 border-1 ">
{inventories.slice(0, 6).map((inventory) => (
<Inventory key={inventory._id} inventory={inventory}></Inventory>
))}
</div>
</div>}
</>
);
};
export default Inventories;

Related

Netflix Clone Images won't show in rows

I'm newer to coding and have been creating a Netflix clone with react.
I'm trying to create rows and fetch the images into the rows with the tmdb API.
I have fetched the data into my console but I can't get the images to render on the UI.
I know its the src={} in my in my Row.jsx file.
Can anyone help me with fixing this please, I've tried following the documentation for tmdb and i still couldn't get it to work.
Thanks in advance :)
Row.jsx
import axios from 'axios';
import React, { useState, useEffect } from 'react';
const Row = ({ title, fetchURL }) => {
const [movies, setMovies] = useState([]);
useEffect(() => {
axios.get(fetchURL).then((response) => {
setMovies(response.data.results);
});
}, [fetchURL]);
console.log(movies);
return (
<>
<h2 className="text-white font-bold md:text-xl p-4">{title}</h2>
<div className="relative flex items-center">
<div id={'slider'}>
{movies?.map((item, id) => {
<div className="w-[160px] sm:w-[200px] md:w-[240px] lg:w-[280px] inline-block cursor-pointer relative p-2">
<img
src={`https://image.tmdb.org/t/p/original/${item?.backdrop_path}`}
alt={item?.title}
/>
</div>;
})}
</div>
</div>
</>
);
};
export default Row;
Requests.js
const requests = {
requestPopular: `https://api.themoviedb.org/3/movie/popular?api_key=${key}&language=en-US&page=1`,
requestTopRated: `https://api.themoviedb.org/3/movie/top_rated?api_key=${key}&language=en-US&page=1`,
requestTrending: `https://api.themoviedb.org/3/movie/popular?api_key=${key}&language=en-US&page=2`,
requestHorror: `https://api.themoviedb.org/3/search/movie?api_key=${key}&language=en-US&query=horror&page=1&include_adult=false`,
requestUpcoming: `https://api.themoviedb.org/3/movie/upcoming?api_key=${key}&language=en-US&page=1`,
};
export default requests;
Home.jsx
import React from 'react';
import Main from '../components/Main';
import Row from '../components/Row';
import requests from '../Requests';
const Home = () => {
return (
<>
<Main />
<Row title="Up Coming" fetchURL={requests.requestUpcoming} />
<Row title="Popular" fetchURL={requests.requestPopular} />
<Row title="Trending" fetchURL={requests.requestTrending} />
<Row title="Top Rated" fetchURL={requests.requestTopRated} />
<Row title="Horror" fetchURL={requests.requestHorror} />
</>
);
};
export default Home;

Fetching the constant value from a component in react to another page

I have a component NFTCard as below, that displays images as card
import React, {useCallback, useState} from "react";
const NFTCard = ({nft}) => {
const [image, setImage] = useState(null);
const handleImage = useCallback(event => {
setImage(event.target.src)
console.log(event.target.src)
console.log(image)
},[image])
return(
//Wrapping the image in a card
<div className="rounded overflow-hidden shadow-lg">
<img className= "object-contain h-50 w-50"
src={nft.meta.image.url.ORIGINAL}
alt={nft.meta.name}
onClick= {handleImage}
/>
<div className="px-1 py-1">
<div className="font-bold text-xs mb-0">{nft.meta.name}</div>
</div>
</div>
)
}
export default NFTCard
What I am trying to do here is whenever an image on a card is clicked, I wish to display it again as an enlarged form in another div element
Here is my main page where i am displaying the image
import Link from 'next/link';
import { useWeb3Context } from '../../context'
import { Web3Address, Web3Button } from '../../components';
import React, { useEffect, useState } from 'react';
import NFTCard from '#/components/NFTCard';
import {useRouter} from 'next/router';
//render only the web3 button if the user is not connected to the web3 provider
const renderNotConnectedContainer = () => (
<div>
<p>Connect Wallet to continue</p>
</div>
);
export const ChooseProductView = () => {
const router = useRouter();
const { address } = useWeb3Context()
const [nfts, setNfts] = useState([]);
// Function to get the details of the NFTs held in the Wallet
const fetchNFTs = async () =>
{
const accounts = await window.ethereum.request({method: 'eth_requestAccounts'});
const response = await fetch(`https://ethereum-api.rarible.org/v0.1/nft/items/byOwner?owner=${accounts[0]}&size=100`)
//limiting the size to 100 so that there is not too much data to fetch
const data = await response.json()
setNfts(data.items)
console.log(data.items)
}
//creating a useEffect to fetch the NFTs details which is an async function
useEffect(() => {
const getNFTs = async () => {
await fetchNFTs()
}
getNFTs()
}, [])
if(!address){
return renderNotConnectedContainer()
}
else{
//rendering the NFTs details via the NFTContainer component
return(
<div className="flex flex-row">
<div className="basis-1/4"> {/*Splitting the screen into 3 parts*/}
<br/>
<div className = "container mx-auto">
<div className="grid grid-cols-2 gap-2 auto-rows-max">
{/*Calling the NFTCard component to render the NFTs details*/}
{nfts.map((nft, index) => {
return <NFTCard nft={nft} key= {index}/>
})
}
</div>
</div>
</div>
<div className="basis-1/2">
<div className="max-w-lg container mx-auto">
<img className="w-full" src={`${router.basePath}/assets/images/Hoodie black label.jpg`} alt="Empty Hoodie"/>
<div className="px-4 py-6">
</div>
</div>
</div>
<div className="basis-1/4">
<Web3Address/>
</div>
</div>
)
}
};
How do i fetch the image url stored in NFTCard with use state into a div element in ChooseProductView?
Thanks a lot in advance

Error : "createSliderWithTooltip is not a function"

Im trying to implement the rc-slider for the web app however the rc-slider tooltip isnt recognized and shows an error of "createSliderWithTooltip is not a function" , which im not sure why .
For implementation of rc-slider i followed the rc-slider documentation which is the same way i have implemeneted in the code of home.js somehow im getting an error in console and nothing shows at all.
Thanks in advance.
Home.js
import React, { Fragment, useEffect , useState } from 'react'
import MetaData from './layouts/MetaData'
import { useDispatch , useSelector } from 'react-redux'
import { getProducts } from '../actions/products'
import Product from './products/Products'
import Loader from './layouts/Loader'
import { useAlert } from 'react-alert'
import Pagination from "react-js-pagination";
import {useParams} from 'react-router-dom'
import Slider from 'rc-slider'
import 'rc-slider/assets/index.css';
const { createSliderWithTooltip } = Slider;**//Error occurs here**
const Range = createSliderWithTooltip(Slider.Range)
const Home = () => {
const [currentPage,setCurrentPage]=useState(1);
const [price,setPrice]=useState([1,1000]);
let params=useParams();
const dispatch= useDispatch();
const alert=useAlert();
const {loading,products,error,productsCount,resPerPage,filteredProductsCount }= useSelector(state=>state.products)
const keyword=params.keyword;
useEffect(() => {
if (error) {
return alert.error("error");
}
dispatch(getProducts(keyword, currentPage));
}, [dispatch, alert, error, currentPage, keyword]);
function setCurrentPageNo(pageNumber) {
setCurrentPage(pageNumber)
}
return (
<Fragment>
{loading ? <Loader>Loading ...</Loader>:(
<Fragment>
<MetaData title={'Buy Electronics , Household Items and Many Others Online'} />
<h1 id="products_heading">Latest Products</h1>
<section id="products" className="container mt-5">
<div className="row">
<Fragment>
<div className="col-6 col-md-3 mt-5 mb-5">
<div className="px-5">
<Range
marks={{
1: `$1`,
1000: `$1000`
}}
min={1}
max={1000}
defaultValue={[1, 1000]}
tipFormatter={value => `$${value}`}
tipProps={{
placement: "top",
visible: true
}}
value={price}
onChange={price => setPrice(price)}
/>
</div>
</div>
</Fragment>
{products.map(product => (
<Product key={product._id} product={product} col={4} />
))}
</div>
</section>
<div className="d-flex justify-content-center mt-5">
<Pagination
activePage={currentPage}
itemsCountPerPage={resPerPage}
totalItemsCount={productsCount}
onChange={setCurrentPageNo}//sets current page no as it changes for state management
nextPageText={'Next'}
prevPageText={'Prev'}
itemClass="page-item"
linkClass="page-link"
/>
</div>
</Fragment>
)
}
</Fragment>
)}
export default Home
Instead of const { createSliderWithTooltip } = Slider;, try this:
const createSliderWithTooltip = Slider.createSliderWithTooltip;
I tried several ways and the only thing that actually worked was downgrading to 9.6.5 rc-slider and now everything is working perfectly
The document hasn't been updated yet since new version. As it seems you want to use Range component, now here the way to do it (thanks to Ashvin-Pal): https://github.com/react-component/slider/issues/825#issuecomment-1084416952
The createSliderWithTooltip has been removed in the new version.
Instead, you can implement your custom handle or tooltip easily like this:
handleRender={renderProps => {
return (
<div {...renderProps.props}>
<SliderTooltip>{round}%</SliderTooltip>
</div>
);
}}
let me know if you have any questions.

content chnge via useState

i'm just starting to learn react, where did i go wrong, can't undestand what am i doing wrong this is my problem
my goal: to ensure that the picture changes as true / false
maybe I am not passing props correctly??
it's my code:
import React, { useState, useEffect } from 'react'
import styles from './styles.module.scss'
import { Link } from 'react-router-dom'
import classNames from 'classnames'
import DjalKokildak from '../../../../assets/images/DjalKokildak.png'
import Turpachaty from '../../../../assets/images/Turpachaty.png'
const Fields = ({image}) => {
const data = [
{
img: {
true : DjalKokildak,
false : Turpachaty
}
}
]
console.log(data)
const [image, setImage] = useState(true)
return (
<div className={styles.container}>
<div className={styles.wrapper}>
<div className={styles.line} />
<div className={styles.contentBlock}>
<div className={styles.titleBlock}>
<h1 className={styles.title}>месторождения</h1>
<p className={styles.text}>“Джал-Кокильдак” и “Турпачаты”</p>
<Link to='/' className={styles.link}>подробнее</Link>
</div>
<div className={styles.actionBlock}>
<button onClick={() => setImage(false)} className={styles.button}>след</button>
<div className={styles.imgBlock}>
{data.map(item => item.img === img && (
<img src={item.img[setImage]}>{image}</img>
))
}
</div>
<button onClick={() => setImage(true)} className={styles.button}>пред</button>
</div>
</div>
</div>
</div>
)
}
export default Fields

not able to display console data in web page

i am beginner in react . when i fetch request from API, i got data in console ,but when i am trying to display data in web page in that time data isn't show.
I want to display data in web page.
here is my console log
https://ibb.co/YLmLQz1
App.js
import React from 'react';
import './App.css';
import Header from './components/Header';
import Movie from './components/Movies';
const App = () => {
return (
<div className="App">
<Header />
<div className='container'>
<Movie />
</div>
</div>
);
}
export default App;
Header.js
In header file i created my navbar and search form
import React, { useState } from 'react'
const Header = () => {
const [search, setSearch] = useState('');
return (
<div className="jumbotron">
<h1 className="display-1">
<i className="material-icons brand-icon">LatestMovie</i> Movie
</h1>
<div className="input-group w-50 mx-auto">
<input
type="text"
className="form-control"
placeholder="Search Your Movie..."
value={search}
onChange={e => setSearch(e.target.value)}
/>
<div className="input-group-append">
<button className="btn btn-dark">
Search Movie
</button>
</div>
</div>
</div>
)
}
export default Header;
Movies.js
here i fetch my movies request throght axios
import React, { useEffect, useState } from 'react'
import Axios from 'axios';
const Movie = () => {
const [movies, setMovie] = useState([]);
const apiurl = "http://www.omdbapi.com/?apikey=642b793e&s=marvel"
const getMovies = async () => {
const res = await Axios.get(apiurl);
console.log(res);
setMovie(res.data.hits);
}
useEffect(() => {
getMovies();
}, []);
return (
<div className='row'>
{
movies && movies.map(movie => (
<div className='col-md-3'>
<div className='card'>
<div className='card-body'>
<h4>{movie.Year}</h4>
</div>
</div>
</div>
))
}
</div>
)
}
export default Movie;

Resources