How to hide Footer component for some pages in react - javascript

i would like to hide footer component in some page
app.js
<div className="App">
<Header setShowMenu={setShowMenu} />
{showMenu ? <Menu navigateTo={navigateTo} setShowMenu={setShowMenu} /> : null}
<Main navigateTo={navigateTo} />
<Footer navigateTo={navigateTo} />
</div>
main.jsx
<div>
<Routes>
<Route path="/" element={<HomePage navigateTo={navigateTo} />} />
<Route path="/precard" element={<PreCard />} />
<Route path="/order" element={<Order />} />
<Route path="/contact" element={<Contact />} />
<Route path="/thankspage" element={<ThanksPage navigateTo={navigateTo}/>} />
<Route path="/*" element={<HomePage />} />
</Routes>
</div>
Note: The Router in index.js
So I want to hide the footer in ./order Page
I hope you guys have solution for me :)

You can use useLocation() hook to check the route path in the <Footer /> component and based on the pathname you can render the <Footer /> component.
Example :
import React from "react";
import { useLocation } from "react-router-dom";
const Footer = () => {
const { pathname } = useLocation();
console.log(pathname);
// you can check a more conditions here
if (pathname === "/thanks") return null;
return <div className="footer">Footer</div>;
};
export { Footer };
App.js
import { Route, Switch, BrowserRouter } from "react-router-dom";
import "./styles.css";
import { Home } from "./pages/Home";
import { Catalog } from "./pages/Catalog";
import { Thanks } from "./pages/Thanks";
import { Header } from "./components/Header";
import { Footer } from "./components/Footer";
import { Page404 } from "./pages/Page404";
const App = () => {
return (
<>
<BrowserRouter>
<Header />
<Switch>
<Route path={"/"} exact>
<Home />
</Route>
<Route path={"/catalog"} exact>
<Catalog />
</Route>
<Route path={"/thanks"} exact>
<Thanks />
</Route>
<Route path={"*"}>
<Page404 />
</Route>
{/* <Redirect to={'/'} /> */}
</Switch>
<Footer />
</BrowserRouter>
</>
);
};
export { App };

Related

How do I redirect from a root path to another root path and still render sub-routes?

import React from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';
import Footer from './components/Footer';
import NavMenu from './components/NavMenu';
import ScrollToTop from './components/ScrollToTop';
import About from './pages/About';
import Contact from './pages/Contact';
import Home from './pages/Home';
import Projects from './pages/Projects';
import Gallery from './pages/Gallery';
export default function App() {
return (
<>
<Router>
<NavMenu />
<ScrollToTop />
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/contact">
<Contact />
</Route>
<Route path="/projects">
<Projects />
</Route>
<Route path="/gallery/">
<Redirect to="/projects" />
<Gallery />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
<Footer />
</Router>
</>
);
}
The problem is that I want it to redirect (example.com/gallery) to (example.com/projects)
but let me use something like (example.com/gallery/photo1) without redirect as well to (example.com/projects)
Render two separate routes, one to redirect from "/gallery" to "/projects", and the other for a specific gallery.
Example:
export default function App() {
return (
<>
<Router>
<NavMenu />
<ScrollToTop />
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/contact">
<Contact />
</Route>
<Route path="/projects">
<Projects />
</Route>
<Route path="/gallery/:galleryId">
<Gallery />
</Route>
<Redirect from="/gallery" to="/projects" />
<Route path="/">
<Home />
</Route>
</Switch>
<Footer />
</Router>
</>
);
}
You can use the exact prop to specify an exact route, meaning sub-routes will not be matched.
<Route exact path="/gallery/">
<Redirect to="/projects" />
<Gallery />
</Route>

Why useContext return undefined?

I have an issue that is useContext return undefined value.
I create a context for collapsing menu like toggle menu. Afterward I added provider into index file to wrap Main component. I go to Main file import CollapseContext but this is file it's not work :( ?
I don't understand why it return undefined.
Below is my code.
src/context/CollapseMenuContext.js
import React, { createContext, useState } from 'react'
export const CollapseContext = createContext()
export default function CollapseProvider({ children }) {
const [isCollapse, setIsCollapse] = useState(false)
const toggleCollapse = () => {
setIsCollapse(!isCollapse)
}
const values = {
isCollapse,
toggleCollapse,
}
return <CollapseContext.Provider value={values}>{children}</CollapseContext.Provider>
}
src/app/index.jsx
import React from 'react'
import Header from '_components/Header'
import CollapseProvider from '../context/CollapseMenuContext.js'
import MainDigistallDesktop from './Main'
function DigistallDesktop() {
return (
<CollapseProvider>
<Header />
<section className='section-content section-content--top mains-screen pb-0' id='checkHeight'>
<MainDigistallDesktop />
</section>
</CollapseProvider>
)
}
export default DigistallDesktop
src/app/Main.jsx
import React, { useContext } from 'react'
import { Route, Switch } from 'react-router-dom'
import OrderRecord from './OrderRecord'
import Sidebar from './components/Sidebar/index'
import Dashboard from './Dashboard'
import Delivery from './Delivery'
import Products from './Products'
import Setting from './Setting'
import { CollapseContext } from '../context/CollapseMenuContext.js'
function MainDigistallDesktop() {
const context = useContext(CollapseContext)
console.info(context)
return (
<div className='container-fluid' style={{ minWidth: '1200px' }}>
<div className='row'>
{/* <div className={`${isCollapse ? 'col-1' : 'col-2'} position-relative`}>
<Sidebar />
</div> */}
<div className='col-10 mx-auto'>
<Switch>
<Route path='/' exact component={Dashboard} />
<Route path='/order-records' exact component={OrderRecord} />
<Route path='/delivery' exact component={Delivery} />
<Route path='/products' exact component={Products} />
<Route path='/setting' exact component={Setting} />
</Switch>
</div>
</div>
</div>
)
}
export default MainDigistallDesktop
result:
Eidt 1:
This is root app file:
export default function App() {
if (process.env.REACT_APP_ENVIRONMENT === 'production') useScript()
return (
<Provider store={store}>
<ToastProvider>
<FirebaseContext.Provider value={{ firebase }}>
<Router history={history}>
<Switch>
<Route path='/sign-in' exact={true} component={SignInPage} />
<Route path='/sign-up' exact={true} component={SignUpPage} />
<Route path='/reset-password' exact={true} component={ForgotPasswordPage} />
<Route path='/reset-password-with-code' component={ResetPasswordPage} />
<Route path='/info' exact={true} component={RedirectGoogleSites} />
<Route path='/policy' exact={true} component={Policy} />
<ProtectedRoute path='/welcome' exact={true} component={Welcome} />
<ProtectedRoute path='/digistall' component={Digistall} /> --> this is index.jsx file
{/* <ProtectedRoute path='/' component={MainPage} /> */}
<ProtectedRoute path='/' component={MainDigistallDesktop} /> --> lead to my app current (Main.jsx)
</Switch>
</Router>
</FirebaseContext.Provider>
</ToastProvider>
</Provider>
)
}
EDIT: You need to wrap CollapseProvider with MainDigistallDesktop. in your app component:
return (
<Provider store={store}>
<ToastProvider>
<FirebaseContext.Provider value={{ firebase }}>
<Router history={history}>
<Switch>
<Route path='/sign-in' exact={true} component={SignInPage} />
<Route path='/sign-up' exact={true} component={SignUpPage} />
<Route path='/reset-password' exact={true} component={ForgotPasswordPage} />
<Route path='/reset-password-with-code' component={ResetPasswordPage} />
<Route path='/info' exact={true} component={RedirectGoogleSites} />
<Route path='/policy' exact={true} component={Policy} />
<ProtectedRoute path='/welcome' exact={true} component={Welcome} />
<ProtectedRoute path='/digistall' component={Digistall} /> --> this is index.jsx file
{/* <ProtectedRoute path='/' component={MainPage} /> */}
<ProtectedRoute path='/' render={() => (
<CollapseProvider>
<MainDigistallDesktop/>
</CollapseProvider>
)} /> --> lead to my app current (Main.jsx)
</Switch>
</Router>
</FirebaseContext.Provider>
</ToastProvider>
</Provider>
)

react-router-dom's Route do not work in my project

I'm in the very first step to create an project, but the react-router-dom's 'Route' just don't work. When i try to use it, just erase all other things in the screen.
My app.js:
import { BrowserRouter, Route } from 'react-router-dom';
import './App.css';
import Header from './components/Header';
import CoinPage from './Pages/CoinPage';
import Homepage from './Pages/Homepage';
function App() {
return (
<BrowserRouter>
<div>
<Header />
<Route path="/" component={Homepage} />
<Route path="/coins/:id" component={CoinPage} />
</div>
</BrowserRouter>
);
}
export default App;
My CoinPage.js:
import React from 'react'
const CoinPage = () => {
return (
<div>
Coin Page
</div>
)
}
export default CoinPage
My Homepage.js:
import React from 'react'
export const Homepage = () => {
return (
<div>
Homepage
</div>
)
}
export default Homepage
My Header.js:
import React from 'react'
/*The header it self:*/
export const Header = () => {
return (
<div>
Header
</div>
)
}
export default Header
When I remove <Route path="/" component={Homepage}/> and <Route path="/coins/:id" component={CoinPage} /> the 'Header' component appears again
You need to wrap all your Route inside Routes Component
import {
BrowserRouter,
Routes,
Route,
} from "react-router-dom";
<BrowserRouter>
<div>
<Header />
<Routes>
<Route path="/" component={Homepage} />
<Route path="/coins/:id" component={CoinPage} />
</Routes>
</div>
</BrowserRouter>
If you are using v6, then component has been replaced by element in Route
<Route path="/" element={<Homepage />} />
<Route path="/coins/:id" element={<CoinPage />} />
Solved!
I needed to change component to element and put each Route in a different Routes tag. Like that:
<BrowserRouter>
<div>
<Header />
<Routes>
<Route path="/" element={<Homepage />} />
</Routes>
<Routes>
<Route path="/coins/:id" element={<Coinpage />} />
</Routes>
</div>
</BrowserRouter>

Detect the url (on reactjs) to hide an element on the page

On a project I just started on reactjs, I should hide an element when the url changes. I searched and did not find something useful.
I would like to hide the Sidebar when the url is not Search.
Thanks to anyone who wants to give me a hand.
import React from 'react';
import { Routes, Route } from "react-router-dom";
import 'bootstrap/dist/css/bootstrap.css';
import 'react-bootstrap';
import './App.css';
import NavBarTop from './components/layouts/header/NavBar_top';
import Sidebar from './components/layouts/Sidebar';
import Home from './components/pages/Home';
import Login from './components/pages/Login';
import Register from './components/pages/Register';
import Search from './components/pages/Search';
import E404 from './components/pages/E404';
function App() {
return (
<>
<div>
<NavBarTop />
<div className="container-fluid maincon">
<Sidebar />
<Routes>
<Route path="/" exact element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route path="/search" element={<Search />} />
<Route path="*" element={<E404 />} />
</Routes>
</div>
</div>
</>
);
}
export default App;
I would like to hide the Sidebar when the url is not Search.
Just render the Sidebar only with the Search component instead of unconditionally with everything.
<div>
<NavBarTop />
<div className="container-fluid maincon">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route
path="/search"
element={(
<>
<Sidebar />
<Search />
</>
)}
/>
<Route path="*" element={<E404 />} />
</Routes>
</div>
</div>
If you wanted to render Sidebar with several routes, then create a layout component. Nested/wrapped Route components are rendered into the Outlet component.
import { Outlet } from 'react-router-dom';
const SidebarLayout = () => (
<>
<Sidebar />
<Outlet />
</>
);
...
<div>
<NavBarTop />
<div className="container-fluid maincon">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route element={SidebarLayout}>
<Route path="/search" element={<Search />} />
... other routes to render with sidebar ...
</Route>
<Route path="*" element={<E404 />} />
</Routes>
</div>
</div>
there are multiple ways to do that.. this is only one...
export default function Wrapper() {
const urlWindow = window.location;
console.log(urlWindow.pathname.split("/")[1]);
const acceptedPaths = ["login", "register", "search", "test"];
return (
<>
<div>
navbar
<div className="container-fluid">
<div className="row">
{acceptedPaths.includes(urlWindow.pathname.split("/")[1]) ? (
<>
<Sidebar />
<MainContent />
</>
) : "Show 404 page"}
</div>
</div>
</div>
</>
);
}
const Sidebar = () => {
return <div className="col-md-2">I'm sidebar</div>;
};
const MainContent = () => {
return <div className="col-md-10">I'm main content</div>;
};
Firstly, you need import useLocation in react-router-dom
import { Routes, Route, useLocation } from "react-router-dom";
and call it in App function to get the current URL path which is used to check against /search for hiding/showing SideBar
function App() {
const location = useLocation();
const currentPath = location.pathname
return (
<>
<div>
<NavBarTop />
<div className="container-fluid maincon">
{currentPath === '/search' && <Sidebar />}
<Routes>
<Route path="/" exact element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route path="/search" element={<Search />} />
<Route path="*" element={<E404 />} />
</Routes>
</div>
</div>
</>
);
}
you can use hook named as useSearchParam
const [searchParams, setSearchParams] = useSearchParams();
to get query/url params as string.

Error: [Header] is not a <Route> component

I continue to run into the above mentioned error despite my efforts to fix them. The terminal claims the application compiles without issue but nothing shows up on the browser. I found the error my looking at the console. Here is the index.js file for the Header component that the error is referring to:
import React from "react";
import { Route, Navigate, Router } from "react-router-dom";
import Navigation from "../../components/Navigation";
import About from "../../components/About";
import Portfolio from "../../components/Portfolio";
import Contact from '../../components/Contact';
import Resume from '../../components/Resume';
class Header extends React.Component {
render() {
return (
<Router>
<header>
<Navigation />
</header>
<div className="content">
<Route exact path="/" render={() => <Navigate to="/about" replace={true}/>} />
<Route path="/about" component={About} />
<Route path="/portfolio" component={Portfolio} />
<Route path="/contact" component={Contact}/>
<Route path="/resume" component={Resume}/>
</div>
</Router>
);
}
}
export default Header;
Here is the App.js:
import React from 'react';
import Header from './components/Header';
import Footer from './components/Footer';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { Routes } from 'react-router-dom';
function App() {
return (
<div>
<Routes>
<Header />
<Footer />
</Routes>
</div>
);
}
export default App;
I can provide further code if it is needed.
In react-router-dom version 6 Routes components can have only Route or React.Fragment as a child component, and Route components can have only Routes or another Route component as parent. Header is not a Route component and fails the invariant.
Move the Router into app and render the Header and Footer components into it instead, then wrap the Route components in Routes.
App
function App() {
return (
<div>
<Router>
<Header />
<Footer />
</Router>
</div>
);
}
Header
Fix the Route components, they no longer use component or render to render the routed components, instead they now use an element prop to render ReactElements, i.e. JSX.
class Header extends React.Component {
render() {
return (
<div>
<header>
<Navigation />
</header>
<div className="content">
<Routes>
<Route path="/" element={<Navigate to="/about" replace />} />
<Route path="/about" element={<About />} />
<Route path="/portfolio" element={<Portfolio />} />
<Route path="/contact" element={<Contact />}/>
<Route path="/resume" element={<Resume />}/>
</Routes>
</div>
</div>
);
}
}
Though it may make more sense to move the routes into the app as content between the header and footer.
function App() {
return (
<div>
<Router>
<Header />
<div className="content">
<Routes>
<Route path="/" element={<Navigate to="/about" replace />} />
<Route path="/about" element={<About />} />
<Route path="/portfolio" element={<Portfolio />} />
<Route path="/contact" element={<Contact />}/>
<Route path="/resume" element={<Resume />}/>
</Routes>
</div>
<Footer />
</Router>
</div>
);
}

Categories