How to manually render specific component and exclude others within specific route - reactjs

I have Header and Footer components, which are used for surrounding internal pages.
I also have a Login component, which appears when the user is not logged in. This component doesn't implement Header or Footer components.
The problem is that I can't prevent Header and Footer components from being rendered with Login component. I can't exclude Login component to be rendered alone.
I tried Switch tag, but didn't get it to work.
import React, { Component } from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import { connect } from 'react-redux';
import * as actions from '../actions';
import Header from "./Header";
import Footer from "./Footer";
import Login from "./Login";
import manageCategories from "./manageCategories";
class App extends Component {
componentDidMount() {
this.props.fetchUser();
}
render() {
return (
<div>
<BrowserRouter>
<div>
<Route exact path="/login" component={Login} />
<Header />
<Route exact path="/manage-categories" component={manageCategories} />
<Footer />
</div>
</BrowserRouter>
</div>
);
}
}
export default connect(null, actions)(App);

You should add a new component that is parallel to the login component to contain the Header and Footer components.
<Route path="/home" component={Layout}/>
<Route exact path="/login" component={Login}/>
and the Layout:
render() {
return <div>
<Header />
<Route exact path={this.props.match.path} component={Home} />
<Route path={`${this.props.match.path}/manageCategories`} component={manageCategories} />
<Route path={`${this.props.match.path}/other`} component={otherComponent} />
<Footer />
</div>
}

Related

I want the component in App not to appear when I go to "contact path"

I have code as below. I want Navigation component to appear on Home and About page, but not in Contact. How can I do that ?
import React, { Component } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';
import Error from './components/Error';
import Navigation from './components/Navigation';
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Navigation />
<Switch>
<Route path="/" component={Home} exact/>
<Route path="/about" component={About}/>
<Route path="/contact" component={Contact}/>
</Switch>
</div>
</BrowserRouter>
);
}
}
export default App;
Just add a condition to check if your route is contact or not and don't render the content of Navigation by returning null. You can get the url using window.location.

How to stop random links from opening with react-router?

I am new to React and practicing with an online website for repairing appliances. I have used react-router and created all my routes in a separate file.
I have a problem though, I can open any link from the address bar like:
http://localhost:3000/<randomword>
I only want routes to be opened that I have declared in my routes component while if I type http://localhost:3000/something, I get an empty page with my header and footer in it.
here are my codes:
Index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from "react-router-dom";
import Routes from './Routes';
import './index.css';
const App = () => {
return(
<BrowserRouter>
<Routes />
</BrowserRouter>
)
}
ReactDOM.render(<App/>,document.getElementById('root'));
App.js:
import React, {Component} from 'react';
import { Route, BrowserRouter } from 'react-router-dom';
import Layout from './Containers/Layout';
import LandingPage from './Containers/Pages/LandingPage';
import About from './Containers/Pages/About';
import Cities from './Containers/Pages/Cities';
import Discount from './Containers/Pages/Discount';
class Routes extends Component {
render(){
return (
<div>
<Layout>
<BrowserRouter>
<Route path="/" render={props => <LandingPage {...props} />} exact component={LandingPage}/>
<Route path="/About" component={About}/>
<Route path="/Cities" component={Cities}/>
<Route path="/Discount" component={Discount}/>
</BrowserRouter>
</Layout>
</div>
);
}
};
export default Routes;
Layout.js:
import React, { Component } from 'react';
import Header from "./Layouts/Header";
import Footer from './Layouts/Footer';
import './Layout.css';
export default class Layout extends Component {
constructor(){
super();
this.state= {
}
}
render() {
return (
<div className="page-container">
<Header/>
<div className="content-wrap">
{this.props.children}
</div>
<Footer/>
</div>);
}
}
Can someone help me figure out how I should stop random random pages to be opened from addressbar?
Just want to start by saying I'm completely self-taught with React so I apologize if this answer is incorrect. However, in my experience with react-router I always have a Switch inside of my BrowserRouter. So your Routes class in app.js should something like this:
class Routes extends Component {
render(){
return (
<div>
<Layout>
<BrowserRouter>
<Switch>
<Route path="/" render={props => <LandingPage {...props} />} exact component={LandingPage}/>
<Route path="/About" component={About}/>
<Route path="/Cities" component={Cities}/>
<Route path="/Discount" component={Discount}/>
</Switch>
</BrowserRouter>
</Layout>
</div>
);
}
};
Just be sure you don't forget to update your imports to
import { Switch, Route, BrowserRouter } from 'react-router-dom';
import { Redirect } from "react-router-dom"
<Route path="/not-found" component={notFound-Component} />
<Redirect to="/not-found" />
This will always redirect you to 404 component if route is not present just make a 404 component and u should add the redirect at the end after all routes are defined

Apply Code Splitting in Ecommerce Mern stack?

I am building an E-Commerce MERN Stack Web Application. The loading time of my Home Page as tested by Lighthouse is more than 12s.
I have hence posted the App.js file and my main main homepage.js file.
How can I implement code splitting on my homepage.js file (using Lazy-Suspense method o any other)?
homepage.js
import React, { Component } from 'react';
import Header from '../header/header';
import About from '../about/about';
import Services from '../services/services';
import Footer from '../footer/footer';
import Navbar from '../navbar/navbar';
export default class Homepage extends Component {
state = {
response: '',
email: '****.com',
password:'****',
message:'',
};
render() {
let loggedIn = this.props.loggedIn;
console.log(loggedIn)
return (
<div className="App">
<Navbar />
<Header resumeData={{name:this.state.email,}}/>
<Services resumeData={{name:this.state.email,}}/>
<About resumeData={{name:this.state.email,}}/>
<Footer resumeData={{name:this.state.email,}}/>
</div>
);
}
}
App.js
import React, { Component } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Homepage from './components/homepage/homepage';
import LogIn from './components/login/login';
import SignUp from './components/signup/signup';
import Reset from './components/reset/reset';
import Account from './components/account/account';
import Verify from './components/verify/verify';
import Shop from './components/shop/shop';
import Cart from './components/cart/cart';
import Checkout from './components/cart/checkout';
import Admin from './components/admin/admin';
import Order from './components/order/order';
import Subscription from './components/order/subscription';
import Subscribe from './components/subscribe/subscribe';
class App extends Component {
render() {
return (
<BrowserRouter>
<Switch>
<Route path="/" component={Homepage} exact/>
<Route path="/shop" component={Shop} />
<Route path="/cart" component={Cart} />
<Route path="/checkout:what" component={Checkout} />
<Route path="/subscribe" component={Subscribe} />
<Route path="/order:oId" component={Order} />
<Route path="/subscription:sId" component={Subscription} />
<Route path="/login" component={LogIn}/>
<Route path="/admin" component={Admin}/>
<Route path="/signup" component={SignUp}/>
<Route path="/reset" component={Reset}/>
<Route path="/account" component={Account}/>
<Route path="/verify/:token" component={Verify}/>
</Switch>
</BrowserRouter>
);
}
}
export default App;
this how you code split your react js app:
import React,{lazy,Suspense} from 'react'
const Child = lazy(()=>import('./ChildComponent'))
const Parent = ()=> <Suspense fallback={<Loader/>}><Child/></Suspense>
here is full detailed explanation : React Code splitting

React - Change component by the router

I start learning about React, and I am working in an application in two parts: when the user is logged and is not.
When the user is not logged, the "/" will show the login page. When is logged, will show the Dashboard page. In Dashboard page, there is a top nav and a sidebar in the left, and in the "center" will show the content of the page. Linke in this image from iMaster:
SO the sidebar will have links, that will update the component that is shown as children of the Dashboard component. I searched about "Nested Routes", but no success.
I'm trying to do in this because I see that if I will show the navs in "all" pages, is better load the navs one time and then update the children os the navs, instead of loading the navs in every page.
Anyone can help?
App.js
import React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import Login from './pages/login';
import Dashboard from './pages/dashboard';
const App = () => (
<div className="App">
<BrowserRouter>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/dashboard" component={Dashboard} />
</Switch>
</BrowserRouter>
</div>
);
export default App;
Dashboard
import React, { Component } from 'react';
//BOOTSTRAP
import 'bootstrap/dist/css/bootstrap.min.css';
import { Col, Container, Row } from 'react-bootstrap';
//BOOTSTRAP
import './styles.css';
import TopSideNavBar from '../../components/TopSideNavBar';
export default class Dashboard extends Component {
render() {
return(
<>
<div className="body">
<TopSideNavBar />
<Container fluid className="content">
<Switch>
<Route path={`${match.path}/component1`} render={Component1}/>
<Route path={`${match.path}/component2`} render={Component2}/>
</switch>
</Container>
</div>
</>
);
}
}
Wrap your component with BrowserRouter and correct access to match.path
export default class Dashboard extends Component {
render() {
return (
<BrowserRouter>
<>
<div className="body">
<TopSideNavBar />
<Switch>
<Route path={`${this.props.match.path}/component1`} component={Component1} />
<Route path={`${this.props.match.path}/component2`} component={Component2} />
</Switch>
</div>
</>
</BrowserRouter>
);
}
}

React Route render different banner image for each route

This is my Layout page where the routing is performed:
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Header from './Header';
import Footer from './Footer';
import Banner from './Banner';
import Home from './Home';
import About from './About';
import Services from './Services';
import Book from './Book';
function Layout() {
return(
<Router>
<Header/>
<Banner/>
<Route exact path="/" component={Home}/>
<Route exact path="/Home" component={Home}/>
<Route exact path="/About" component={About}/>
<Route exact path="/Services" component={Services}/>
<Route exact path="/Book" component={Book}/>
<Footer/>
</Router>
)
}
export default Layout;
This is the Banner component:
import React from 'react';
import Jumbotron from 'react-bootstrap/Jumbotron';
function Banner(props) {
const heroStyle = {
backgroundImage: "url(" + require('../images/home-hero-image.jpg') + ")"
};
return (
<div>
<Jumbotron style={heroStyle}>
<h1 className="centerme">Live your best life</h1>
<p className="centerme">
Get Coaching
</p>
</Jumbotron>
</div>
);
}
export default Banner;
Basically I have a different banner image for Home, About and Services and want to update the image url depending on the page that is currently in use.
I'm not sure what the best practice way to achieve this would be.
You should be able to render the Banner after adding the router props to it, and then access location.pathname inside Banner.
Note withRouter and BannerWithRouter component:
import React from 'react'
import { BrowserRouter as Router, Route, withRouter } from 'react-router-dom'
import Header from './Header'
import Footer from './Footer'
import Banner from './Banner'
import Home from './Home'
import About from './About'
import Services from './Services'
import Book from './Book'
const BannerWithRouter = withRouter(({ location }) => <Banner {...props} />)
function Layout() {
return (
<Router>
<Header />
<BannerWithRouter />
<Route exact path='/' component={Home} />
<Route exact path='/Home' component={Home} />
<Route exact path='/About' component={About} />
<Route exact path='/Services' component={Services} />
<Route exact path='/Book' component={Book} />
<Footer />
</Router>
)
}
export default Layout
Banner component: (Note you now have a prop called location)
import React from 'react'
import Jumbotron from 'react-bootstrap/Jumbotron'
function Banner({ location }) {
const heroStyle = {
backgroundImage: 'url(' + require('../images/home-hero-image.jpg') + ')'
}
console.log(location.pathname)
if (location.pathname === '/about') {
return 'This is the about page'
}
return (
<div>
<Jumbotron style={heroStyle}>
<h1 className='centerme'>Live your best life</h1>
<p className='centerme'>
<a href='#' className='jumbotron-book-now-button'>
Get Coaching
</a>
</p>
</Jumbotron>
</div>
)
}
export default Banner

Resources