I have my app.js in that App.js I want to show some components when clicked on that router.
Here is my App.js code
import React from 'react';
import {BrowserRouter, Route} from 'react-router-dom';
import Header from './Header'
import Slider from './Slider';
import Section from './Section';
import Footer from './Footer';
import Register from './Register';
class IndecisionApp extends React.Component {
render() {
return (
<BrowserRouter>
<div className="wrapper">
<Header/>
<Route path="/register" component={Register}></Route>
<Slider />
<Section />
<Footer />
</div>
</BrowserRouter>
);
}
}
export default IndecisionApp;\
I want to hide Section and Slider components when I click on Router.
You are doing react-router wrong.
The correct way is this
<BrowserRouter>
<div className="wrapper">
<Header/>
<Switch>
<Route path="/register" component={Register}></Route>
</Switch>
<Slider />
<Section />
<Footer />
</div>
</BrowserRouter>
more on react router
https://reacttraining.com/react-router/web/guides/quick-start
Let say you have a home component and that only show as landing page including section and slide.
So there should be basically two route one is for landing another is for register, like follows
<Route path="/register" component={Register} />
<Route exact path="/" component={Home} />
But as your home/landing/index page should show section and slide together so I change the home route a little bit and finally it sum up with the following code
<BrowserRouter>
<div className="wrapper">
<Header />
<div>
<Link to="/">Home</Link>
<Link to="/register">Register</Link>
</div>
<Switch>
<Route path={"/register"} component={Register} />
<Route
exact
path="/"
render={() => (
<React.Fragment>
<Home />
<Slider />
<Section />
</React.Fragment>
)}
/>
</Switch>
<Footer />
</div>
</BrowserRouter>
Please make me clear if your idea is something different
Related
This is my App.js
import "./App.css";
import Header from "./component/layout/Header/Header.js";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import React from "react";
import Home from "./component/Home/Home.js";
function App() {
return (
<Router>
<Header />
<Route exact path="/" component={Home} />
<Footer />
</Router>
);
}
export default App;
This is my Home.js
const Home = () => {
return (
<Fragment>
<div className="banner">
<p>Welcome to My Website</p>
</div>
</Fragment>
);
};
export default Home;
Edit: i managed to remove the black page after wrapping the Route but the text in Home.js doesn't show "Welcome to My Website"
<Routes>
<Route exact path="/" component={Home} />
</Routes>
this code ^ removed the blank page but the result is that the text from Home.js "Welcome to My Website" didn't show. How can I route correctly to the Home component?
If you are using v6 react-router-dom, you have to replace component to element
<Routes>
{/* <Route exact path="/" component={Home} /> */}
<Route exact path="/" element={<Home />} />
</Routes>
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>
);
}
I installed react-router-dom to switch between navbar elements. The library does not want to cooperate with my project. After clicking on the navbar element I am not redirected to the required component. Sometimes when I click on a selected item the menu moves slightly to the left. My code looks like this:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
ReactDOM.render(
<App />, document.getElementById('root'));
Navbar.js
import React, { useState } from "react";
import App from '../components/App'
import About from '../components/About';
import Services from '../components/Services';
import Contact from '../components/Contact';
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
const Navbar = () => {
const [navLinkOpen, navLinkToggle] = useState(false);
const handleNavLinksToggle = () => {
navLinkToggle(!navLinkOpen);
};
const renderClasses = () => {
let classes = "navlinks";
if(navLinkOpen) {
classes += " ' ' + active";
}
return classes;
};
return (
<nav>
<div className="logo">
<h4>Delightartco</h4>
</div>
<ul className={renderClasses()}>
<Router>
<li className="link"><Link to={"/home"}>Home</Link></li>
<li className="link"><Link to={"/about"}>About</Link></li>
<li className="link"><Link to={"/services"}>Services</Link></li>
<li className="link"><Link to={"/contact"}>Contact</Link></li>
<Switch>
<Route path="/home" component={App}>
</Route>
<Route path="/about" component={About}>
</Route>
<Route path="/services" component={Services}>
</Route>
<Route path="/contact" component={Contact}>
</Route>
</Switch>
</Router>
</ul>
<div onClick={handleNavLinksToggle} className="hamburger-toggle">
<i className="fas fa-bars fa-lg"></i>
</div>
</nav>
)
}
export default Navbar;
App.js
import React from 'react';
import '../../src/App.css';
import Navbar from './Navbar';
import Wrapper from './Wrapper';
import {Content, Winnie, Testimonials, Values, Secrets, Footer} from '../components/Content';
function App() {
return (
<div>
<Navbar />
<Wrapper />
<Content />
<Winnie />
<Testimonials />
<Values />
<Secrets />
<Footer />
</div>
)
}
export default App;
These are few issues in your code:
App is your root React component, and you gave it a route: <Route path="/home" component={App}></Route>. This is causing a recursive / infinite loop. App component inside App component.
Code structure looks complex.
Here is a proposed fixed code:
index.jsx:
ReactDOM.render(<App />, document.getElementById("root"));
App.jsx:
export default function App() {
return (
<StrictMode>
<Routes />
</StrictMode>
);
}
Routes.jsx:
export default function Routes() {
return (
<Router>
{/* Route components would be visible only at their route */}
<Switch>
<Route exact path="/about" component={About}></Route>
<Route exact path="/services" component={Services}></Route>
<Route exact path="/contact" component={Contact}></Route>
</Switch>
{/* Below components would be visible always at UI */}
<Navbar /> {/* Top navigation Link's */}
<Wrapper />
<Content />
<Winnie />
<Testimonials />
<Values />
<Secrets />
<Footer /> {/* Bottom navigation Link's */}
</Router>
);
}
There are several things to keep in mind when using react-router.
The Router or BrowserRouter component should wrap all your routes and your links. Generally, if your app does not need more than one Router, its better to wrap your whole App with the Router.
The Link component's job is to simply navigate to the page and can be used anywhere you want to show a link to someplace e.g. in the Navbar.
The Route (not Router) component's placement is very important. It should be placed where you want to render the content. In your code you are rendering the routes in the Navbar and are unable to see the routes being rendered due to invalid / improper structure.
Navbar.js
Your Navbar should only contain the links while the Router should be on the top-level and the Switch / Routes should be placed where you want to render the content.
function Navbar() {
return (
<nav>
{/* Move `Router` to top-level e.g. in App.js */}
<ul>
<li className="link">
<Link to={"/home"}>Home</Link>
</li>
<li className="link">
<Link to={"/about"}>About</Link>
</li>
<li className="link">
<Link to={"/services"}>Services</Link>
</li>
<li className="link">
<Link to={"/contact"}>Contact</Link>
</li>
</ul>
{/* Move `Switch and Routes` to where you want to render the content e.g. in Content.js */}
</nav>
);
}
App.js
function App() {
return (
<Router>
<div>
<Navbar />
<Wrapper />
<Switch>
<Route path="/home" component={App}></Route>
<Route path="/about" component={About}></Route>
<Route path="/services" component={Services}></Route>
<Route path="/contact" component={Contact}></Route>
</Switch>
<Winnie />
<Testimonials />
<Values />
<Secrets />
<Footer />
</div>
</Router>
);
}
I created the component NotFound and it works fine when I go to a page that doesn't exist. But the same page it's appearing in all my pages, not only the one that doesn't exist. This is the component:
import React from 'react'
const NotFound = () =>
<div>
<h3>404 page not found</h3>
<p>We are sorry but the page you are looking for does not exist.</p>
</div>
export default NotFound
And this is how I used it in the main page:
class MainSite extends Component {
render () {
return (
<div>
{/* Render nav */}
<Route path='/dashboard' component={Nav} />
<Route path='/retrospectives' component={Nav} />
<Route path='/users' component={Nav} />
<Route path='/projects' component={Nav} />
{/* Dashboard page */}
<ProtectedRoute exact path='/dashboard' component={DashboardPage} />
{/* Retrospectives page */}
<ProtectedRoute exact path='/retrospectives' component={RetrospectivesPage} />
{/* Users page */}
<ProtectedRoute exact path='/users' component={UsersPage} />
{/* Projects page */}
<ProtectedRoute exact path='/projects' component={ProjectsPage} />
{/* Retrospective related pages */}
<Route exact path='/retrospectives/:retrospectiveId' component={Retrospective} />
<Route exact path='/join-retrospective' component={JoinRetrospective} />
<ProtectedRoute exact path='/create-retrospective/:retrospectiveId' component={Retrospective} />
{/* OnBoarding pages */}
<ProtectedRoute exact path='/beta-code' component={BetaCodeAccess} />
<Route exact path='/auth-handler' component={AuthHandler} />
<Route exact path='/join-organization' component={JoinOrganization} />
</div>
)
}
}
export default MainSite
As you can see I use <Route path="*" component={NotFound} /> to create the 404 pages, but that component is appearing in every existing page as well. How can I fix this?
Try this one:
import { Switch, Route } from 'react-router-dom';
<Switch>
<Route path='/dashboard' component={Nav} />
<Route path='/retrospectives' component={Nav} />
<Route path='/users' component={Nav} />
<Route path='/projects' component={Nav} />
<Route path="" component={NotFound} />
</Switch>
All below example works fine:
<Route path="" component={NotFound} /> // empty ""
<Route path="*" component={NotFound} /> // star *
<Route component={NotFound} /> // without path
Or if you want to return a simple 404 message without any component:
<Route component={() => (<div>404 Not found </div>)} />
For those who are looking for an answer using react-router-dom v6, many things had changed. Switch for example doesn't exists anymore, you have to use element instead of component, ... Check this little example to get you an idea:
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import './index.css'
import App from './App'
const Test = () => (
<h1>404</h1>
)
ReactDOM.render(
<React.StrictMode>
<Router>
<Routes>
<Route path='/' element={<App />} />
<Route path='*' element={<Test />}/>
</Routes>
</Router>
</React.StrictMode>,
document.getElementById('root')
)
With this you are defining your home route and all the other routes will show 404. Check the official guide for more info.
Try This:
import React from "react";
import { Redirect, Route, Switch, BrowserRouter } from 'react-router-dom';
import HomePage from './pages/HomePage.jsx';
import NotFoundPage from './NotFoundPage.jsx';
class App extends React.Component {
render(){
return(
<BrowserRouter>
<Switch>
<Route exact path='/' component={HomePage} />
<Route path="*" component={NotFoundPage} />
</Switch>
</BrowserRouter>
)
}
}
export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Simply import Switch from react-router-dom and wrap all your Routes in the Switch Component. Also Important here is to note to keep your 404Page component at the very bottom(just before your switch ending tag) This way it will match each component with its route first. If it matches, it will render the component or else check the next one. Ultimately if none matching routes will be founded, it will render 404Page
react router is a headache for new coders. Use this code format. This is class component but you can make a functional component and use it.
import React from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import HomePage from './pages/HomePage.jsx';
import NotFoundPage from './NotFoundPage.jsx';
import Footer from './Footer';
class App extends React.Component {
render(){
return(
<Router>
<Routes>
<Route exact path='/' element={HomePage} />
<Route path="*" element={NotFoundPage} />
</Routes>
<Routes>
<Route path="/" element={Footer}/>
</Routes>
</Router>
)
}
}
export default App;
(Updated for clarity) I have the following structure for my App:
<Layout />
/components/
<Header />
<Navigation />
<Stage />
<Footer />
/pages/
<Home />
<About />
<Contact />
My thinking is to have the <Navigation> element isolated, and imported into the parent <Header> (and later, Site Map). All components are then staged into the parent <Layout>, which is fed into the <div id="root">
The content of my /pages/ Components are successfully called and rendered with the code below. However this page content is rendered inside of my <header> element, breaking the page hierarchy.
My intention is to have the <Switch> device render the /pages/ Components within the <Stage> parent Component.
Any attempt to move the <Switch> element to the <Stage> component causes the whole app to not load/render.
import React from 'react';
import {
BrowserRouter as Router, Route, Link, Switch
} from 'react-router-dom';
import Home from './../pages/Home';
import About from './../pages/About';
import Contact from './../pages/Contact';
export default class Navigation extends React.Component {
render() {
return (
<Router>
<div className="navigation">
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
{/*
Below should be repositioned outside of <header>, in Stage component
*/}
<div className="stage">
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</Switch>
</div>
</div>
</Router>
)
}
}
My question is: How can I have the Router render the required /page/ Components inside my <Stage> component, when selected from the <Navigation> component.
Since all the reacttraining.com examples are single-page, I'm struggling to determine if I'm making a logic mistake in assuming how my app should be optimally constructed, or a programming error in recreating a relation between the two elements with react-router v4.
All you need to do is to separate these two divs as you are wrapping stage inside the header. And as the Component needs to be rendered in a single element you need another div around the whole content:
export default class Navigation extends React.Component {
render() {
return (
<Router>
<div>
<div className="navigation">
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
</div>
<div className="stage">
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</Switch>
</div>
</div>
</Router>
);
}
}
Update:
Updating my answer:
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
const Header = () => <h1>I'm a header</h1>;
const Navigation = () => (
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
);
const Stage = () => (
<div>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</div>
);
const Footer = () => <h6>Footer</h6>;
const Home = () => <h3>Home</h3>;
const About = () => <h3>About</h3>;
const Contact = () => <h3>Contact</h3>;
const App = () => (
<Router>
<div>
<Header />
<Navigation />
<Stage />
<Footer />
</div>
</Router>
);
render(<App />, document.getElementById('root'));
And here is the working version:
https://codesandbox.io/s/v21BD37NX