Using Fullpagejs with react-router-dom - reactjs

I am building a website using Fullpage.js, React, and react-router-dom. I create a Link in the second section in the Fullpage component, and I want this Link can take me to another route (/anotherPage):
// Fullpage.js
import React, { useEffect } from "react";
import { Link } from "react-router-dom";
import { initFullpage } from "./initFullpage";
const Fullpage = () => {
useEffect(() => {
initFullpage();
}, []);
return (
<div id="fullpage">
<div class="section">Some section</div>
<div class="section">
<Link to="/anotherPage">
Go to a special page.
</Link>
</div>
<div class="section">Some section</div>
<div class="section">Some section</div>
</div>
);
};
export default Fullpage;
Additionally, I need another Link to go back from /anotherPage route back to the second section in the Fullpage component.
I made a demo here.
As you can try, if you click the link on the second section, react can route you to AnotherPage, but the navigation dots provide by Fullpage package is still there, and you can even scroll up and down, though this will cause errors. Also, if you click Go back, it will also break the App.
How to do it right? Thanks for your help!
Here is my App.js:
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Fullpage from "./components/Fullpage";
import AnotherPage from "./components/AnotherPage";
export default function App() {
return (
<Router>
<Switch>
<Route exact path="/">
<Fullpage />
</Route>
<Route exact path="/anotherPage">
<AnotherPage />
</Route>
</Switch>
</Router>
);
}

I found I don't need to use Fullpage.js to achieve the "scroll-full-page" effect. It's actually easy to achieve by CSS. Have a look at scroll-snap-type.
// index.html
<div class="container">
<section class="page">
Page one
</section>
<section class="page">
Page two
</section>
</div>
// css
.container{
width: 100%;
height: 100vh;
scroll-snap-type: y mandatory;
overflow: auto;
}
.page{
scroll-snap-align: start;
height: 100vh;
}
Then you can have Fullpage.js type scrolling effect. Then you can use react-router-dom without problem.

Related

React/gatsby with Lottie animation bottlenecks the DOM

I have a weird issue with Lottie animations in React/Gatsby. I've tried many plugins like react-lottie, lottie-react, lottie-web etc. They all start bottlenecking the dom while navigating back and forth pages.
I've made an example with the issue: https://elegant-aryabhata-490c95.netlify.app/
If you navigate between the pages Go to page 2 and Go back to the homepage soon enough the DOM stops and the animation starts rendering extra stuff as well.
I am rendering the animations like so:
import * as React from "react"
import { Link } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"
import Lottie from "lottie-react"
import contactAnimation from "../components/assets/contact.json"
const SecondPage = () => (
<Layout>
<SEO title="Page two" />
<h1>Hi from the second page</h1>
<p>Welcome to page 2</p>
<Link to="/">Go back to the homepage</Link>
<Lottie animationData={contactAnimation} style={{ width: "600px" }} />
</Layout>
)
export default SecondPage
It looks like a memory leak or something but have no idea how to debug this.
Well, I sorted it out myself, turns out it is a memory leak and happens if some of the Lottie animations us a 'repeater'
Solved it by stringify the JSON: const contactAnimation = JSON.parse(JSON.stringify(data))
So full code becomes:
import * as React from "react"
import { Link } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"
import Lottie from "lottie-react"
import data from "../components/assets/contact.json"
const SecondPage = () => {
const contactAnimation = JSON.parse(JSON.stringify(data))
return (
<Layout>
<SEO title="Page two" />
<h1>Hi from the second page</h1>
<p>Welcome to page 2</p>
<Link to="/">Go back to the homepage</Link>
<Lottie animationData={contactAnimation} style={{ width: "600px" }} />
</Layout>
)
}
export default SecondPage

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')} />

how change background color in different pages

i am two page in reactjs
pageOne.js:
import React from "react";
import { Link } from "react-router-dom";
import "./pageOne.css";
const PageOne = () => {
return (
<div>
one
<br />
<Link to="/pageTwo">Two Page</Link>
</div>
);
};
export default PageOne;
pageTwo.js:
import React from "react";
import { Link } from "react-router-dom";
import "./pageTwo.css";
const PageTwo = () => {
return (
<div>
two
<br />
<Link to="/">One Page</Link>
</div>
);
};
export default PageTwo;
i am define two css files for change background color when page loaded.
pageOne.css
body {
background-color: whitesmoke !important;
}
pageTwo.css
body {
background-color: crimson !important;
}
it's problem.in pageOne background color is crimson and in pageTwo background color is crimson.
sample
As I said earlier, there is only one body tag in the DOM tree by default. So when you try to style it whatever comes last will override the previous ones and in your case, the page two style will override the page one style.
To solve this, you got several options, but I will go with the easiest one. You can make a container for each of your pages and then assign a colour to that container to make the whole page background as you desired (You can simply make a layout component then wrap each of the components within it and with similar approach make it reusable). So, for example, you can create your first page like this:
<div className="crimson">
two
<br />
<Link to="/">one Page</Link>
</div>
and style it like this:
.crimson {
background-color: crimson;
min-height: 100vh; /* minimum height of page would be equal to available view-port height */
}
This goes the same for your other page. But you need to consider you have to remove the default margins from the body itself to prevent any disorder.
Working Demo:
I would solve this with Layout component:
const Layout = ({ backgroundColor = '#fff', children }) => (
<div style={{ backgroundColor }} className="layout">
{children}
</div>
)
then remove your css(and try not to use important in your css)
<Layout backgroundColor="#fff"><PageOne /></Layout>
and
<Layout backgroundColor="#f00"><PageTwo /></Layout>

How to direct to a new page when a button is clicked using ReactJS?

I am working in React.I have created a button ,which on click should lead the user to the newpage.I made a component About and imported it as well.
I created a function routeChange which would direct to a new page on Clicking the button.But when the button is clicked I am not being directed to any page .
Instead I get an error.
Probably there is not any error with folders.
I imported my About Component as:
import React from 'react';
import {Navbar,NavbarBrand, Jumbotron, Button} from 'reactstrap';
import './App.css';
import Description from './Description';
import './description.css';
import {useHistory,withRouter} from "react-router-dom";
import About from './About';
function App() {
const history=useHistory();
routeChange = () =>{
this.history.push('/About');
}
return (
<withRouter>
<Navbar color="dark">
<div className="container">
<NavbarBrand className="navbar-brand abs" href="/">
Cheat Sheet
</NavbarBrand>
</div>
</Navbar>
<Jumbotron>
<p className="lead">Quick Review ,Revision And Mnemonic Are Always Good</p>
<hr my-2/>
<p className="lead">Page is still under Construction</p>
<Button onClick={routeChange} className="About"color="primary">About Us</Button>
</Jumbotron>
<div className="img-thumbnail">
<Description/>
</div>
<div className="footer">
©Abhilekh Gautam all right reserved.
<p>Follow<a rel="noopener noreferrer"href="https://www.quora.com/profile/Abhilekh-Gautam-1" target="_blank">Abhilekh Gautam</a> On quora</p>
</div>
</withRouter>
)
}
export default App;
a couple issues here.
change function App (){} to const App = () => {} its going to help with your binding later because arrow functions are interpreted differently from declarative functions
this function needs some help
routeChange = () =>{
this.history.push('/About');
}
first of all you have to declare the function as a constant because App is a functional component not a class component.
second of all because App is a functional component you don't need the this keyword because routeChange is an arrow function and is bound to App
your final function should look like this:
const routeChange = () => {
history.push('/About');
}
make your button onClick handler an anonymous function so it is called on click only and not on render
<Button onClick={routeChange}/>
this code makes the route change function get called when the button renders. Instead change it to
<Button onClick={() => routeChange()}
make sure /About is a route to another component in your router or else you will get a 404 error or hit your no match component (if you have one)
your final product should look something like this
in app.js
import React from 'react';
import {Navbar,NavbarBrand, Jumbotron, Button} from 'reactstrap';
import './App.css';
import Description from './Description';
import './description.css';
import {useHistory,withRouter, BrowserRouter, Route, Switch} from "react-router-dom";
import About from './About';
function App() {
return (
<>
<Navbar color="dark">
<div className="container">
<NavbarBrand className="navbar-brand abs" href="/">
Cheat Sheet
</NavbarBrand>
</div>
</Navbar>
<BrowserRouter>
<Switch>
<Route exact path='/' component={Home}/>
<Route exact path='/About' component={About}
</Switch>
</BrowserRouter>
</>
)
}
then your home component would look like this:
import {useHistory} from 'react-router-dom'
const Home = () => {
const history = useHistory();
const routeChange = () => {
history.push('/About');
}
return (
<>
<Jumbotron>
<p className="lead">Quick Review ,Revision And Mnemonic Are Always Good</p>
<hr my-2/>
<p className="lead">Page is still under Construction</p>
<Button onClick={() => routeChange()} className="About"color="primary">About Us</Button>
</Jumbotron>
<div className="img-thumbnail">
<Description/>
</div>
<div className="footer">
©Abhilekh Gautam all right reserved.
<p>Follow<a rel="noopener noreferrer"href="https://www.quora.com/profile/Abhilekh-Gautam-1" target="_blank">Abhilekh Gautam</a> On quora</p>
</div>
</>
)
}
export default Home

How to mobile collapse navbar from Materialize CSS in Svelte?

I am trying to use the javascript functions in Materialize CSS in my Svelte Project. I have a navbar which is called in app.svelte. I have called M.AutoInit(); in the script tags of app.svelte as so:
<script>
import "../node_modules/materialize-css/dist/css/materialize.min.css";
import "../node_modules/materialize-css/dist/js/materialize.min.js";
import { Router, Route } from "svelte-routing";
import { setupI18n, isLocaleLoaded, locale } from "./services/i18n";
import { derived } from "svelte/store";
import Home from "./pages/Home.svelte";
import About from "./pages/About.svelte";
import Navbar from "./layout/Navbar.svelte";
$: if (!$isLocaleLoaded) {
setupI18n({ withLocale: "jp" });
}
M.AutoInit();
</script>
{#if $isLocaleLoaded}
<Router>
<Navbar />
<Route path="/" component={Home} />
<Route path="/about" component={About} />
</Router>
{:else}
<p>Loading...</p>
{/if}
I add the required javascript in my Navbar.svelte file as in the materialize css documentation here.
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.sidenav');
var instances = M.Sidenav.init(elems, options);
});
However click the mobile hamburger button does not bring out the side menu.
In addition, browser console says that "options" is not defined.
Hello stackoverflow and svelte community. I have fixed the above issue, and will document my steps here:
In my Navbar.svelte file, I re-wrote the javascript into a function:
function mobileNav() {
var elems = document.querySelectorAll(".sidenav");
var instances = M.Sidenav.init(elems);
}
Then, I bound the function to the mobile hamburger button by adding "on:click={mobileNav}" to the hamburger button, as is possible in svelte! Here it is using the Navbar as in documentation:
<nav>
<div class="nav-wrapper">
Logo
menu</i>
<ul class="right hide-on-med-and-down">
<li>Sass</li>
<li>Components</li>
<li>Javascript</li>
<li>Mobile</li>
</ul>
</div>
</nav>
<ul class="sidenav" id="mobile-demo">
<li>Sass</li>
<li>Components</li>
<li>Javascript</li>
<li>Mobile</li>
</ul>
In the navbar documentation, the function takes the arguments (elems, options) however removing options fixed the problem entirely.

Resources