How to run animation only once while current session? - javascript

I have a website page that uses react-anime and react-typing-animation. My issue is to animate some elements displayed on it only once while the current session. So, if my site was opened on the main page, the animation would launch, and then, after switching a few pages and returning back to the main page, the animation wouldn't be executed again.
I've thought about sessionStorage, but I don't understand how to use it with these libraries.
Here's all the code:
index.js
import React from 'react'
import styles from './Index.module.css'
import Greeting from '../components/main/Greeting'
import Yelnya from '../components/main/Yelnya/Yelnya'
import BlueLakes from '../components/main/BlueLakes'
import Gallery from "../components/main/Gallery";
export default function Home() {
return (
<div className={styles.container}>
<Greeting />
<Yelnya />
<BlueLakes />
<Gallery />
</div>
)
}
Greeting.js
import React from 'react'
import styles from './Greeting.module.css'
import Tag from './Tag'
import Anime from "react-anime";
import Typing from "react-typing-animation"
export default function Greeting() {
return (
<div className={styles.root}>
<div className={styles.title}>
<Typing startDelay={50} speed={100}>
Explore Belarusian nature with us.
</Typing>
</div>
<div className={styles.hint}>
<Anime
opacity={[0,1]}
translateX={[-50,0]}
duration={3000}
delay={4200}
>
<p className={styles.hintTitle}>Go to:</p>
</Anime>
<Tag title="#Yelnya" link="/#yelnya" delay={4400}/>
<Tag title="#Blue lakes" link="/#blue-lakes" delay={4500}/>
<Tag title="#Galleries" link="/#galleries" delay={4600}/>
</div>
</div>
)
}
Tag.js
import React from 'react'
import styles from './Tag.module.css'
import Link from 'next/link'
import Anime from "react-anime";
export default function Tag({ title, link, delay }) {
return (
<Anime
opacity={[0,1]}
translateY={[50,0]}
duration={3000}
delay={delay}
>
<Link href={link}>
<div className={styles.tag}>
<p className={styles.text}>{title}</p>
</div>
</Link>
</Anime>
)
}

I made an example for using LocalStorage and handle animation with them
export default function App() {
const animated = !!localStorage.getItem("animated");
if (animated === false) {
localStorage.setItem("animated", true);
}
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{!animated && (
<Anime
opacity={[0, 1]}
translateX={[-50, 0]}
duration={3000}
delay={500}
>
<p>Go to:</p>
</Anime>
)}
{animated && <p>Go to:</p>}
</div>
);
}
also you can test it here

Related

Swapped useState to useSelector(redux) and it's not working anymore

build this part of the code with useState initially and everything worked perfectly but I need to share this state with my main component (no relationships between those two) and decided to use Redux but def something is wrong, any ideas?
Here's the console error:
MUI: The value provided to the Tabs component is invalid.
None of the Tabs' children match with "-1".
You can provide one of the following values: 0, 1, 2.
import { React } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import '../../css/SideBar.css';
import { UilSignOutAlt } from '#iconscout/react-unicons';
import Logo from '../../../../assets/img/companyLogo.jpg';
import { SidebarData } from '../../Data/Data';
import { setDashboard } from '../../../../app/actions';
function SideBar() {
const selected = useSelector((state) => state.dashboard);
const dispatch = useDispatch();
return (
<div className="Sidebar">
{/* logo */}
<div className="logo">
<img src={Logo} alt="logo" />
<span>Company Name</span>
</div>
{/* menu */}
<div className="menu">
{SidebarData.map((item, index) => (
/* eslint-disable */
<div
role='menu'
className={selected === index ? 'menuItem active' : 'menuItem'}
key={index}
onClick={() => dispatch(setDashboard(index))}
onKeyDown={() => dispatch(setDashboard(index))}
>
<item.icon />
<span>{item.heading}</span>
</div>
))}
<div className='menuItem'>
<UilSignOutAlt />
</div>
</div>
</div>
);
}
export default SideBar;

components not rendering in react-paginate

I am trying to implement react pagination on local json data, using react-paginate. The buttons are clickable and the css works fine. However, any components after the first page are not being rendered. The entire page (except for the header) goes blank. The pagination buttons were the only components visible at first, but once I applied some styling to the buttons, they vanished as well (just basic styling like background colours etc). Now nothing is displayed unless I'm on the first page of cards displayed. Can you please help me with this issue?
This is my dashboard.tsx
import React, { useState } from 'react'
import logo from '../assets/logo192.png'
import courses from '../data/courses.json'
import star_on from '../assets/star_on.png'
import star_off from '../assets/star_off.png'
import next from '../assets/next.png'
import left_arrow from '../assets/left-arrow.png'
import right_arrow from '../assets/right-arrow.png'
import ReactPaginate from 'react-paginate'
function Dashboard(this: any) {
let on = false
const turnOn = (event: any) => {
if (on)
{event.target.src = star_off
on = false
}
else {
event.target.src = star_on
on = true
}
}
const [cards, setCards] = useState(courses)
const [pageNumber, setPageNumber] = useState(0)
const cardsPerPage = 6
const pagesVisited = pageNumber * cardsPerPage
const displayCards = cards
.slice(pagesVisited, pagesVisited + cardsPerPage)
.map(card => {
return (
<div className='dashboard--card'>
<div className='line1'>
<div><img src ={card.image} alt ="course" className='card--image'></img></div>
<div className='card--title'>{card.title}</div>
<div className='card--author'>{card.author}</div>
<div> <img className='card--star' src={star_off} alt="star" onClick={turnOn} /></div>
<div className='card--price'>Rs {card.price}/-</div>
<div className='card--discounted'>Rs {card.discounted}/-</div>
<div className='card--cartbtn'> ADD TO CART</div>
<img className='card--arrow' src ={next} alt ="arrow"/>
</div>
<div className='line2'>
<div className='reactbtn'>React</div>
<div className='reactbtn'>React</div>
</div>
</div>
)
})
const pageCount = Math.ceil(cards.length / cardsPerPage)
const changePage = (selected: React.SetStateAction<number>) => {
setPageNumber(selected)
}
return (
<div className='dashboard--main'>
<div className='dashboard--banner'>
<div className='dashboard--banner-title'>
Discover Latest Courses on React
</div>
<div className='dashboard--banner-logo'>
<img src={logo} alt ="react-logo" className='react-logo'/>
</div>
</div>
<div className='dashboard--items'>
<div className='dashboard--left'>
<p className='dashboard--all-courses'>All courses</p>
<div className='dashboard'>
{displayCards}
<div className='dashboard--paginate'>
<ReactPaginate
previousLabel= {<img className='paginate--arrow-left' src ={left_arrow} alt ="prev"/>}
nextLabel = {<img className='paginate--arrow-right' src ={right_arrow} alt ="next"/>}
pageCount={pageCount}
onPageChange ={changePage}
containerClassName ={"paginationBtns"}
pageLinkClassName={"pageBtns"}
previousLinkClassName ={"prevBtn"}
nextLinkClassName ={"nextBtn"}
disabledClassName ={"disabledBtn"}
activeClassName ={"activeBtn"}/>
</div>
</div>
</div>
<div className='dashboard--right'>
hello
</div>
</div>
</div>
)
}
export default Dashboard
App.tsx
import React from 'react';
import Dashboard from './components/Dashboard';
import Wishlist from './components/Wishlist';
import Error from './components/Error';
import Cart from './components/Cart';
import Profile from './components/Profile';
import logo from './assets/logo.png'
import cart from './assets/cart.svg'
import profile from './assets/profile.svg'
import { BrowserRouter,Routes,Route, NavLink} from 'react-router-dom';
import './App.css';
function App() {
return (
<BrowserRouter>
<nav className='navbar'>
<li><NavLink to="/"><img className='navbar--logo' src={logo} alt ="Dashboard"/></NavLink></li>
<div className='navbar--links'>
<li><NavLink className="single" to="/">COURSES</NavLink></li>
<li><NavLink className="single" to ="/wishlist">MY WISHLIST</NavLink></li>
</div>
<div className='navbar--icons'>
<li><NavLink className='navbar--cart' to="/cart"><img src={cart} alt ="Cart"></img></NavLink></li>
<li><NavLink className='navbar--profile' to="/profile"><img src={profile} alt ="profile"></img></NavLink></li>
</div>
</nav>
<Routes>
<Route path='/' element={<Dashboard/>}/>
<Route path='wishlist' element={<Wishlist/>}/>
<Route path ='cart' element={<Cart/>}/>
<Route path ='profile' element ={<Profile/>}/>
<Route path='*' element={<Error/>}/>
</Routes>
</BrowserRouter>
);
}
export default App;
The other pages in App.tsx haven't been implemented yet, they only display basic components, and they they don't interfere with the working of dashboard.tsx. I don't know why the previously rendrered pagination buttons are vanishing. I have tried to inspect my code, and changed the values of the number of cards rendered per page. No matter the number, only the page is rendered. If someone has gone through this before and/or has a solution to this, that would be great.
I resolved the question! I hadn't destructured the 'selected' object while accessing it in my changePage function. Hope this is useful for anyone else who comes across this issue in the future

React.JS Context API Problem (Rendering Problem)

I'm currently trying to implement a e-commerce project. My question is about Context API and Reducer.
Cannot able to render price and other details of the product. in Cart Component
Context.Js ;
Here is my Context.js
Reducer.JsHere is the Reducer.js
And My Product Component Code is ;
import './Product.css'
import AddBoxIcon from '#material-ui/icons/AddBox';
import { Context } from "./Context"
import React, {useContext} from "react"
function Product({title,price,image,id}) {
const {addtoBasket} = useContext(Context)
/*
function alertUser() {
alert(`${title} added to your card`)
}
function addBasket(){
console.log(title,price)
}
function firedFunctions(){
alertUser()
addBasket()
}
*/
return (
<div className="product">
<div className="product__info">
<img src={image} alt=""></img>
<p className="title">{title}</p>
<div className ="price__add" >
<h4>Price : {price} $</h4>
<div onClick={() => addtoBasket(title, price, image,id)}>
<AddBoxIcon className="btn" />
</div>
</div>
</div>
</div>
)
}
export default Product
And My Cart Component Code is ;
import React, {useContext} from 'react'
import './Cart.css'
import {Context} from "./Context"
import Product from "./Product"
function Cart() {
const {basket} = useContext(Context)
console.log(basket) // Expected: Empty Array
return (
<div className="cart">
<div className="cart__left">
<h2>Your Products</h2>
<div>
{basket.map((product) =>(
<h4>{product}</h4>
{/*why product give me just a title of product*/}
))}
</div>
</div>
<div className="cart__right">
<h2>Total</h2>
</div>
</div>
)
}
export default Cart
And this is the output when i click the button v.1(console) ;
I want to see Price and image either.
You are passing three parameters to addToBasket function, however it is receiving just one object.
Probably what you needs is:
<div onClick={() => addtoBasket({title, price, image, id)}>
I've just replicate it in codesandbox, this is the right answer, take a look:
https://codesandbox.io/s/awesome-violet-fr7np?file=/src/index.js

Functional component is not being rendered

I am trying to display the songs but for some reason my songs component is not even being executed. The console.log statement inside the Songs component is also not being logged to console. Also no errors of any sort are detected at all.
Here is my body component from which I am calling the Songs component
import './body.css'
import React from 'react'
import Header from './Header'
import { useStateValue } from './StateProvider';
import FavoriteIcon from '#material-ui/icons/Favorite';
import PlayCircleFilledIcon from '#material-ui/icons/PlayCircleFilled';
import MoreHorizIcon from '#material-ui/icons/MoreHoriz';
import Songs from './Songs.js'
function Body( {spotify}) {
const [{recently_played},dispatch] = useStateValue();
return (
<div className="body">
<Header spotify={spotify} />
<div className="body__info">
<img src={recently_played?.images[0].url} alt=""/>
<div className="body__infotext">
<strong>PLAYLIST</strong>
<h2>On Repeat</h2>
<p>{recently_played?.description}</p>
</div>
</div>
<div className="body__songs">
<div className="body__icons">
<PlayCircleFilledIcon className="body__shuffle"/>
<FavoriteIcon fontSize="large"/>
<MoreHorizIcon />
</div>
{recently_played?.tracks.items.map(item=>{
<Songs track={item.track} />
})}
</div>
</div>
)
}
export default Body
Here is the Songs component
import React from "react";
import './SongRow.css'
function Songs({ track }) {
console.log(track);
return (
<div className="songRow" >
<img className="songRow__album" src={track.album.images[0].url} alt="" />
<div className="songRow__info">
<h1>{track.name}</h1>
<p>
{track.artists.map((artist) => artist.name).join(", ")} -{" "}
{track.album.name}
</p>
</div>
</div>
);
}
export default Songs;
You are not returning anything inside the map
{recently_played?.tracks.items.map(item => {
return <Songs track={item.track} />;
})}
[or] use the shorthand version of arrow function
{recently_played?.tracks.items.map(item => <Songs track={item.track} />)}

React component is getting rendered twice

I am newbie to Reactjs and trying to develop the static website. so far was able to render the few components like carasouel and cards.
however, in the recent development , the specific <div> is getting rendered twice. while troubleshooting, i see that <div> is coming twice, but in the code , have written <div> just once. scratching my head how to fix this.
here is the code :
App.js
import React, { Fragment, Component } from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import { Button } from "react-bootstrap";
import Carasel from "./Components/carosel";
import Cards from "./Components/cards";
class App extends Component {
render() {
return (
<Router>
<Carasel />
<Cards />
</Router>
);
}
}
export default App;
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
rootElement
);
card.js
import React, { Component } from "react";
import img1 from "../test/person1.jpg";
import "bootstrap/dist/css/bootstrap.min.css";
import { Button } from "react-bootstrap";
import "./card-style.css";
class Card extends Component {
render() {
const mouse = this.props.mouse;
return (
<div className="card text-center">
<div className="overflow">
<img src={img1} alt="image1" />
</div>
<div className="card-body text-dark" />
<h4 className="card-title">{mouse}</h4>
<p className="card-text text-secondary">lorem20</p>
<a href="#" className="btn btn-outline-success">
Go Anywhere
</a>
</div>
);
}
}
export default Card;
cards.js
import React, { Component } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Card from "./card";
class Cards extends Component {
render() {
return (
<div className="container-fluid d-flex justify-content-center">
<div className="row">
<div className="col-md-4">
<Card mouse="DevOps" />
</div>
<div className="col-md-4">
<Card mouse="Cloud Computing" />
</div>
<div className="col-md-4">
<Card mouse="Machine Learning" />
<Card />
</div>
</div>
</div>
);
}
}
export default Cards;
now the issue is : <div className="card text-center"> is getting rendered twice at the end. not getting where and which is the issue . while troubleshooting, seems the component is stateful ? please suggest
It seems you have an aditional card with no mouse in Cards? In the div at the end? I dont think that is supposed to be there.

Categories