How to render an animation depending on state? - reactjs

I have a navbar that I need to animate using React Anime. Navbar contains Link component, which gets delay and duration as props.
Here's the code of navigation bar:
import React, {useContext, useState} from 'react'
import Link from '../Link'
import ImageLink from '../ImageLink'
import styles from './Navigation.module.css'
import { ThemeContext } from '../../theme'
let isPassed= false
export default function Navigation() {
const theme = useContext(ThemeContext)
return (
<div className={styles.root} style={{"--height-after": 6 + 'px'}}>
<div>
<ImageLink
href="/"
alt="logo"
src={theme.name === 'light' ? '/images/logo/Logo.svg' : '/images/logo/LogoBlack.svg'}
className={styles.logo}
delay={3200}
/>
</div>
<div className={styles.item}>
<Link
href="/contact"
duration={isPassed}
delay={2100}
>
Contact
</Link>
</div>
<div className={styles.item}>
<Link
href="/about"
duration={isPassed === false ? 1500 : 0}
delay={2300}
>
About us
</Link>
</div>
<div className={styles.item}>
<Link
href="/trails"
duration={isPassed === false ? 1500 : 0}
delay={2500}
>
All trails
</Link>
</div>
</div>
)
}
Here's the code of the Link component:
import React from 'react'
import styles from './Link.module.css'
import NextLink from 'next/link'
import Anime from "react-anime";
export default function Link({ href, children, className, delay, duration }) {
return (
<Anime
translateY={[-15,0]}
opacity={[0,1]}
duration={duration}
delay={delay}
>
<NextLink href={href}>
<a className={styles.link + ' ' + className}>{children}</a>
</NextLink>
</Anime>
)
}
The task is to handle the animation state, and if the animation has been already passed in the current browser session, not to animate it on page reload.
My first idea was to use sessionStorage, but then I've decided to declare a new variable isPassed in the navbar component and animate links depending on its value. So... Can I somehow change isPassed value when the animation is passed

Related

How to change Icon on Navlink when active?

I'm making a tab bar for phone in react js and i have icons on it. I'm using React Router to perform the routes. Right now im able to change the icon color when it is active using an .active class. Is there a way I can change the Icon File when the route is active? Here is the code attached below.
import React, { Component } from 'react';
import {NavLink} from 'react-router-dom';
import home_icon_stroke from './home_icon_stroke.svg';
import explore_icon_stroke from './explore_icon_stroke.svg';
import activity_icon_stroke from './activity_icon_stroke.svg';
import library_icon_stroke from './library_icon_stroke.svg';
import profile_icon_stroke from './profile_icon_stroke.svg';
import './Phonetabbar.css';
export default class Phonetabbar extends Component {
render() {
return (
<div className="phone-tabbar-layout" >
<div className="fixed" >
<div className="phone-tabbar-list">
<div className="tabbar-cell">
<NavLink exact to="/" >
<img src={home_icon_stroke} ></img>
</NavLink>
</div>
<div className="tabbar-cell">
<NavLink to="/explore" >
<img src={activity_icon_stroke} ></img>
</NavLink>
</div>
</div>
</div>
</div>
)
}
}
Maybe you want to try passing the isActive function to Navlink, setting a state in it.
<NavLink exact to="/"
isActive={(match, location)=>{
if(match){
//set isActive state true
}
return match;
}
>
<img src={isActive?home_icon_stroke:anotherImg} ></img>
</NavLink>

how to use react routing to switch between pages

i am currently building a shopping website . i finished the homepage and i have to make routing for other pages
i have 3 main files: App.js, Menuitem.js (which is to execute props), and Homepage.js (which also is used to apply executing props from sections array which includes titles and background images and sections paths)
this is the App js
import React from "react";
import Homepage from './Homepage'
import "./styles.css";
import './Homepage.css'
import {Route, Switch} from "react-router-dom";
const Hatspage=function() {
return(
<div>
<h1>
Hats page
</h1>
</div>
)
}
function App() {
return (
<div>
<Switch>
<Route exact path='/'component={Homepage}/>
<Route path='/hats'component={Hatspage}/>
</Switch>
</div>
);
}
export default App
Menuitem.js
import React from 'react'
import {WithRouter} from 'react'
const Menuitem= function(props){
return(
<div className='card' style={{ backgroundImage: `url(${props.imageUrl})` }} >
<div className='text-frame'>
<h1 className='title'>{props.title}</h1>
<p className='subtitle'>shop now</p>
</div>
</div>
)
}
export default Menuitem
Homepage.js
import React from "react";
import sections from './directory-components';
import Menuitem from "./menu-item-components";
const arrayOne=[sections.slice(0,3)]
const arrayTwo=[sections.slice(3,)]
function extract(item){
return(
<Menuitem
title={item.title} imageUrl={item.imageUrl}/>
)
}
function Homepage(){
return(
<div className='directory-menu'>
<div className='content'>
{sections.slice(0,3).map(extract) }
</div>
<div className='second'>
{sections.slice(3,).map(extract) }
</div>
</div>
)
}
export default Homepage
so i need for example when i click on hats picture i switch to hats page . how to do that
image attached
Thanks in advance
reactjs routing
You can do two different approaches. Both of them will require an extra prop that will be the actual url you want to access when clicking the menu item.
Assuming you modify your section array to look like this:
[{title: 'Your title', imageUrl: 'your-image.jpg', linkUrl: '/hats'}]
And you modify your extract function to add the url value as a prop in the MenuItem component:
function extract(item){
return(
<Menuitem
title={item.title} imageUrl={item.imageUrl} linkUrl={item.linkUrl} />
)
}
You can do this
First one: Using a Link component from react router:
import React from "react";
import { Link } from "react-router-dom";
const Menuitem= function(props){
return(
<Link to={props.linkUrl}>
<div className='card' style={{ backgroundImage: `url(${props.imageUrl})`
}} >
<div className='text-frame'>
<h1 className='title'>{props.title}</h1>
<p className='subtitle'>shop now</p>
</div>
</div>
</Link>
)
}
Now you will have to add extra styling because that will add a regular a tag, but I like this approach because for example you can open the link in a new tab since it is a regular link.
Using the history prop.
import React from "react";
import { useHistory } from "react-router-dom";
const Menuitem= function(props){
const history = useHistory()
const goToPage = () => history.push(props.linkUrl)
return(
<div className='card' style={{ backgroundImage: `url(${props.imageUrl})`
}} onClick={goToPage} >
<div className='text-frame'>
<h1 className='title'>{props.title}</h1>
<p className='subtitle'>shop now</p>
</div>
</div>
)
}
This approach is a basic on click so if you press the component it will go to the selected page, this will work but keep in mind that event bubbling will be harder if you add more on clicks inside the menu item, so please be aware of that.
You should fire an event inside your MenuItem in order to redirect the user
import { useHistory } from 'react-router-dom'
const history = useHistory()
<img onClick={() => history.push('/hats')} />

react-scroll target element not found

I have a Navbar React component with a Link component which needs to scroll down to Section component when clicked. I have implemented react-scroll, however, when I click on the Link component, I get target element not found in the browser console.
The Navbar component:
import React, { Component } from "react";
import { Link, animateScroll as scroll, scroller } from "react-scroll";
class Navbar extends Component {
render() {
return (
<div>
<ul>
<li>
<Link to="section1" activeClass="active" spy={true} smooth={true}>
Section 1
</Link>
</li>
</ul>
</div>
);
}
}
export default Navbar;
And the App.js file:
import React from "react";
// Styling
import "./styles/App.css";
// Components
import Navbar from "./components/Navbar";
import SectionOne from "./components/SectionOne";
function App() {
return (
<div className="App">
<div>
<Navbar />
<SectionOne id="section1"/>
</div>
</div>
);
}
export default App;
I used this repo as a reference, however, things don't work. What have I missed here?
I have implemented a div inside of the SectionOne component
<div id="section-one-wrapper">Section One content...</div>
and then specified that id in the Link component:
<Link to="section-one-wrapper" activeClass="active" spy={true} smooth={true}>
Section 1
</Link>
and it worked.

How To Make Popup Modal Appear When Clicking a Link?

I am trying to create a Login Modal Form for an application. However, I want the popup to appear when I click a link versus a button. In other words, when I click the login link in my navbar, I don't want to be redirected to another page entirely. I just want the modal to pop up.
I'm very new to ReactJS, so I'm not sure how to go about this. Could somebody please help me understand how to get this function to work? I'd really appreciate it.
Additionally, if anyone knows of some great resources on how to implement a proper login form, I would also greatly appreciate that. I found a few on CodePen, but none of them really show a clear and approachable way on how to build this component. At least, for a beginner like me.
Located below is my code. Also, if it helps, I provided the link to the site I am currently using as a reference to build this code.
Resource: https://react-bootstrap.github.io/components/modal/
App.js
import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom'
import Navbar from './components/Navbar/navbar.js';
import Footer from './components/Footer/footer.js';
import Home from './pages/Home/home.js';
import Login from './pages/Login/login.js';
import Languages from './pages/Languages/languages.js';
function App() {
return (
<div className="App">
<BrowserRouter>
<Navbar/>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/login" component={Login}/>
<Route path="/languages" component={Languages}/>
</Switch>
</BrowserRouter>
<Footer />
</div>
);
}
export default App;
Navbar.js
import React from 'react';
import { Link } from 'react-router-dom';
import './navbar.css';
const Navbar = () => {
return (
<nav className="navbar navbar-expand-sm navbar-dark px-sm-5">
<div className="container">
<Link to='/'>
<div className="navbar-brand">
<i class="fas fa-globe fa-2x"></i>
</div>
</Link>
<ul className="navbar-nav align-items-right">
<li className="nav-item ml-5">
<Link to="/login" className="nav-link">
Log In
</Link>
</li>
<li className="nav-item ml-5">
<Link to="/signup" className="nav-link">
Sign Up
</Link>
</li>
</ul>
</div>
</nav>
)
}
export default Navbar;
Login.js
import React, { Component } from 'react';
// import { connect } from 'react-redux';
import Modal from 'react-bootstrap/Modal';
import Button from 'react-bootstrap/Button';
import './login.css';
class Login extends Component {
constructor(props, context) {
super(props, context);
this.handleShow = this.handleShow.bind(this);
this.handleClose = this.handleClose.bind(this);
this.state = {
show: false,
};
}
handleClose() {
this.setState({ show: false });
}
handleShow() {
this.setState({ show: true });
}
render() {
return (
<>
<Button variant="primary" onClick={this.handleShow}>
Launch demo modal
</Button>
<Modal show={this.state.show} onHide={this.handleClose}>
<Modal.Header closeButton>
<Modal.Title>Login</Modal.Title>
</Modal.Header>
<Modal.Body>...</Modal.Body>
<Modal.Footer>
<Button variant="danger" onClick={this.handleClose}>
Cancel
</Button>
</Modal.Footer>
</Modal>
</>
);
}
}
export default Login;
Let's refactor your Navbar to be a class-component instead. We're going to need to keep track of state and pass down a binded function to the Login modal.
Additonally, it looks like you won't need a Login page anymore, so let's extract that markup so that its in a component instead. We'll call it LoginModal
Navbar.js
import React from "react"
import { Link } from 'react-router-dom';
import './navbar.css';
import LoginModal from "./components/LoginModal"
class Navbar extends React.Component{
state = {
modalOpen: false
}
handleModalOpen = () => {
this.setState((prevState) => {
return{
modalOpen: !prevState.modalOpen
}
})
}
render(){
return (
<div>
<nav className="navbar navbar-expand-sm navbar-dark px-sm-5">
<div className="container">
<Link to='/'>
<div className="navbar-brand">
<i class="fas fa-globe fa-2x"></i>
</div>
</Link>
<ul className="navbar-nav align-items-right">
<li className="nav-item ml-5">
<a onClick={this.handleModalOpen} className="nav-link">
Log In
</a>
</li>
<li className="nav-item ml-5">
<a onClick={this.handleModalOpen} className="nav-link">
Sign Up
</a>
</li>
</ul>
</div>
</nav>
<LoginModal
modalOpen={this.state.modalOpen}
handleModalOpen={this.handleModalOpen}
/>
</div>
)
}
}
export default Navbar;
Notes about Navbar:
It has a component state that keeps track of the status of the modal.
The modal is placed right at the end of nav jsx.
Replaced the Link components with standard a-tags and gave them an
onClick handler
The onClick handler, handleModalOpen toggles a value in our state
called openModal.
openModal and handleModalOpen gets passed down to the LoginModal
component.
So now let's refactor Login to be LoginModal.
LoginModal
import React from 'react';
import Modal from 'react-bootstrap/Modal';
import Button from 'react-bootstrap/Button';
import './login.css';
const LoginModal = (props) => {
return (
<>
<Modal show={props.modalOpen} onHide={props.handleModalOpen}>
<Modal.Header closeButton>
<Modal.Title>Login</Modal.Title>
</Modal.Header>
<Modal.Body>...</Modal.Body>
<Modal.Footer>
<Button variant="danger" onClick={props.handleModalOpen}>
Cancel
</Button>
</Modal.Footer>
</Modal>
</>
);
}
export default LoginModal;
Notes about LoginModal
We were able to remove a lot of the original logic now that
LoginModal is strictly just responsible for consuming props and
displaying content.
We use the prop value, props.modalOpen which is passed down from
Navbar, it gets set to true when the button is clicked inside the
Navbar component. So show={true} will display the modal
Similarly, we use another prop, props.handleModalOpen which toggles
the state in the parent component. When you call that function in the modal, it updates state.modalOpen in the parent to false.
That updated value gets passed back down to LoginModal, setting
props.modalOpen to false, so show={false} thus closing the modal.
Lastly App.js can now just be:
App.js
import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom'
import Navbar from './components/Navbar/navbar.js';
import Footer from './components/Footer/footer.js';
import Home from './pages/Home/home.js';
import Languages from './pages/Languages/languages.js';
function App() {
return (
<div className="App">
<BrowserRouter>
<Navbar/>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/languages" component={Languages}/>
</Switch>
</BrowserRouter>
<Footer />
</div>
);
}
export default App;

How to enable the React Semantic UI Modal to stretch across the full screen?

This is my first time trying to use Meteor with ReactJs and React Semantic UI, and having issues on rendering the Semantic UI modal. What I am trying to achieve is to click on the button and open up the modal overlaying on the whole browser, in reference to the React Semantic Modal Manual But what I have right now is that the modal is rendered partially on the screen, as seen from the attached screenshots. Can anyone please help? Thanks in advance.
Main.js
import {Meteor} from 'meteor/meteor';
import React from 'react';
import ReactDOM from 'react-dom';
import {routes} from "../imports/routes/routes";
Meteor.startup(() => {
ReactDOM.render(routes, document.getElementById('app'));
});
Site.js:
import React from 'react';
import { Header, Button, Modal } from 'semantic-ui-react';
import PrivateHeader from './PrivateHeader';
import Sidebar from './Sidebar';
import ModalExample from './Modal';
export class Site extends React.Component {
render() {
return (
<div>
<PrivateHeader/>
<Sidebar/>
<div className="page">
<div className="ui padded one column grid">
<div className="column">
<ModalExample/>
</div>
</div>
</div>
</div>
);
}
}
export default Site;
ModalExample.js
import React from 'react'
import { Button, Header, Icon, Modal } from 'semantic-ui-react'
const ModalBasicExample = () => (
<Modal trigger={<Button>Basic Modal</Button>} basic size='fullscreen'>
<Header icon='archive' content='Archive Old Messages' />
<Modal.Content>
<p>Your inbox is getting full, would you like us to enable automatic archiving of old messages?</p>
</Modal.Content>
<Modal.Actions>
<Button basic color='red' inverted>
<Icon name='remove' /> No
</Button>
<Button color='green' inverted>
<Icon name='checkmark' /> Yes
</Button>
</Modal.Actions>
</Modal>
)
export default ModalBasicExample
Sidebar.js
export const Sidebar = (props) => {
return (
<div className="ui inverted vertical left fixed menu" >
<a className="item" href="/">
<img src='/images/logo.png' className="ui mini right spaced image"/>
Semantics UI Test
</a>
<div className="item">
<div className="header">Hosting</div>
<div className="menu">
<a className="item">Shared</a>
<a className="item">Dedicated</a>
</div>
</div>
<div className="item">
<div className="header">Support</div>
<div className="menu">
<a className="item">E-mail Support</a>
<a className="item">FAQs</a>
</div>
</div>
</div>
)
};
export default Sidebar;
Thanks to Saad's comment mentioning the className that I found out that it was due to Semantic UI will add a ui page modals dimmer transition visible active className when the modal is opened. This causes a conflict to my existing page className which is used in other pages, but because of Meteor and React, the various scss are compressed together.
I suggest to run this.show('fullscreen') with an onClick event on trigger button like the following :
<Button onClick={this.show('fullscreen')}>Show Modal</Button>
ModalExample.js
import React, { Component } from 'react'
import { Button, Modal } from 'semantic-ui-react'
class ModalExample extends Component {
state = { open: false }
show = size => () => this.setState({ size, open: true })
close = () => this.setState({ open: false })
render() {
const { open, size } = this.state
return (
<div>
<Button onClick={this.show('fullscreen')}>Show Modal</Button> // Triggering button
<Modal size={size} open={open} onClose={this.close}>
<Modal.Header>
Delete Your Account
</Modal.Header>
<Modal.Content>
<p>Are you sure you want to delete your account</p>
</Modal.Content>
<Modal.Actions>
<Button negative>
No
</Button>
<Button positive icon='checkmark' labelPosition='right' content='Yes' />
</Modal.Actions>
</Modal>
</div>
)
}
}
export default ModalExample
Source

Resources