i am trying to create a simple react project. it has a navbar, sidebar and the main content area.
first a home component is displayed.
home.js
import { useState } from "react";
import Navbar from "../navbar/navbar";
import Sidebar from "../sidebar/sidebar";
import "./style.css";
import { useSelector, useDispatch } from 'react-redux'
function Home() {
const sidebarOpen = useSelector((state) => state.sidebarOpenState);
return (
<>
<Navbar />
<div className="home-box d-flex">
{sidebarOpen && <div className="p-2 flex-fill"><Sidebar /></div>}
</div>
</>
);
}
export default Home;
my navbar has a button which will change state sidebarOpen.
my sidebar looks like this->
sidebar.js
import "./style.css";
import { Link } from "react-router-dom";
function Sidebar() {
return (
<div className="divSidebar">
<ul>
<li>
<Link to="/chess">
<img className="sidebar-img" src="images/sidebar/chess.png"></img>
<span className="sidebar-text">Chess</span>
</Link>
</li>
<li>
<Link to="/volleyball">
<img
className="sidebar-img"
src="images/sidebar/volleyball.png"
></img>
<span className="sidebar-text">Volleyball</span>
</Link>
</li>
<li>
<Link to="/football">
<img
className="sidebar-img"
src="images/sidebar/football.png"
></img>
<span className="sidebar-text">Football</span>
</Link>
</li>
<li>
<Link to="/tabletennis">
<img
className="sidebar-img"
src="images/sidebar/table-tennis.png"
></img>
<span className="sidebar-text">TableTennis</span>
</Link>
</li>
<li>
<Link to="/rugby">
<img className="sidebar-img" src="images/sidebar/rugby.png"></img>
<span className="sidebar-text">Rugby</span>
</Link>
</li>
</ul>
</div>
);
}
export default Sidebar;
when i click on chess, the respective component should be loaded.
chess.js
function Chess() {
return (
<>
<h1>chess</h1>
</>
);
}
export default Chess;
but the problem is my sidebar disappears. i only want the main content area to be changed nothing else. can someone help? let me know if u want to some more code.
---------edit
i have added console.log in two places. one is in the navbar where the toggle method is defined and another is in redux store where toggle state is defined. both the places onclick is working. i am able to see message but the sidebar is not getting rendered.
---------edit 2
App.js
import "./App.css";
import Navbar from "./components/navbar/navbar";
import { Route, Routes } from "react-router-dom";
import Chess from "./components/chess/chess";
import Volleyball from "./components/volleyball/volleyball";
import Football from "./components/football/football";
import TableTennis from "./components/tabletennis/tabletennis";
import Rugby from "./components/rugby/rugby";
import Home from "./components/home/home";
function App() {
return (
<div className="App">
<Routes>
<Route exact path="/" element={<Home />} />
<Route
path="/chess"
element={
<>
<Navbar />
<Chess />
</>
}
/>
<Route
path="/volleyball"
element={
<>
<Navbar />
<Volleyball />
</>
}
/>
<Route
path="/tabletennis"
element={
<>
<Navbar />
<TableTennis />
</>
}
/>
<Route
path="/football"
element={
<>
<Navbar />
<Football />
</>
}
/>
<Route
path="/rugby"
element={
<>
<Navbar />
<Rugby />
</>
}
/>
</Routes>
</div>
);
}
export default App;
When you click on Chess you navigate to "/chess"
So if u can't see your Navbar there, is because you have to render it there too.
Or, render the Navbar outside de Routes from BrowsterRouter.
We need to see the components rendering on "/chess" and the react-router-dom config on app.js (or on the top lvl you declare it)
----- edit ------
Ok, look this:
function App() {
return (
<BrowserRouter>
<NavBar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/test" element={<Test />} />
</Routes>
</BrowserRouter>
);
}
If you refactor your brower like this is gona be more clean to understand the code and even easy to escale.
As u see, the navBar is outside the Routes, so its gona be visible in all routes.
then you can have this:
-> one path -> one element
your Links on navbar (or sidebar or whatelse) are gona work good.
i found a way. i rendered <Sidebar /> again in all my child components.
like this->
chess.js
function Chess() {
const sidebarOpen = useSelector((state) => state.sidebarOpenState);
return (
{sidebarOpen && (
<div className="p-2 flex-fill">
<Sidebar />
</div>
)}
)
}
this way when i click on button the state is updated and sidebar is rendered automatically.
Related
I have made landing page where onClick of button it redirects to the Menus page/component where I have declared Navbar component & here only I want to render the different news category component on click of multiple nav menus of Navbar.
By using react-router-dom V6 how can I render different categories of news component underneath of Navbar.
Below is the code which I have tried yet.
App.js
import React from 'react';
import {Routes,Route} from 'react-router-dom';
import LandingPage from './Components/LandingPage';
import Menus from './Component/Menus;
const App = () => {
return (
<>
<Routes>
<Route path='/' element={<LandingPage/>} />
<Route path='menus' element={<Menus/>} />
</Routes>
</>
)
};
export default App;
Menus.js
import Navbar from './Navbar';
const Menus = () => {
return (
<div>
<Navbar/>
</div>
);
};
export default Menus;
Navbar.js
import '../Styles/Navbar.css';
import Entertainment from './Entertainment';
import Business from './Business';
import Health from './Health';
import Science from './Science';
import Sports from './Sports';
import Technology from './Technology';
import {Link,Route,Routes} from 'react-router-dom';
import {useState} from 'react';
const Navbar = ()=>{
const [isMobile,setIsMobile] = useState(false);
return(
<>
<nav className="navbar">
<h3 className="logo">theNews</h3>
<ul className={isMobile?'nav-links-mobile':'nav-links'}
onClick={()=>setIsMobile(false)}>
<Link to='/business' className='business'><li>Business</li></Link>
<Link to='/fun' className='fun'><li>Entertainment</li></Link>
<Link to='/health' className='health'><li>Health</li></Link>
<Link to='/science' className='science'><li>Science</li></Link>
<Link to='/sports' className='sports'><li>Sports</li></Link>
<Link to='/tech' className='tech'><li>Technology</li></Link>
</ul>
<button className='mobile-menu-icon' onClick={()=>setIsMobile(!isMobile)}>
{isMobile? <i className='fas fa-times'></i>:<i className='fas fa-bars' ></i>}
</button>
</nav>
<div>
<Routes>
<Route path='business' element={<Business/>}/>
<Route path='health' element={<Health/>} />
<Route path='science' element={<Science/>} />
<Route path='sports' element={<Sports/>} />
<Route path='tech' element={<Technology/>} />
<Route path='fun' element={<Entertainment/>} />
</Routes>
</div>
</>
)
}
export default Navbar;
If I understand your question correctly you are wanting to render Menus on the "/menus" path, and then also render sub-routes in Navbar being rendered by Menus. In react-router-dom v6 route paths are now always exactly matched, and the "/menus" root path precludes matching and rendering sub-routes.
The solution is to append a "*" wildcard matcher to the root path to allow additional route matching.
<Routes>
<Route path="/" element={<LandingPage/>} />
<Route path="/menus/*" element={<Menus/>} />
</Routes>
Additionally, in Navbar you are rendering relative route paths but specifying absolute route links. These should be in agreement. Remove the leading "/" character from the links so they are also relative to the "/menus" route path.
const Navbar = () => {
const [isMobile, setIsMobile] = useState(false);
return(
<>
<nav className="navbar">
<h3 className="logo">theNews</h3>
<ul className={isMobile?'nav-links-mobile':'nav-links'}
onClick={()=>setIsMobile(false)}>
<Link to='business' className='business'><li>Business</li></Link>
<Link to='fun' className='fun'><li>Entertainment</li></Link>
<Link to='health' className='health'><li>Health</li></Link>
<Link to='science' className='science'><li>Science</li></Link>
<Link to='sports' className='sports'><li>Sports</li></Link>
<Link to='tech' className='tech'><li>Technology</li></Link>
</ul>
<button className='mobile-menu-icon' onClick={()=>setIsMobile(!isMobile)}>
{isMobile? <i className='fas fa-times'></i>:<i className='fas fa-bars' ></i>}
</button>
</nav>
<div>
<Routes>
<Route path='business' element={<Business/>}/>
<Route path='health' element={<Health/>} />
<Route path='science' element={<Science/>} />
<Route path='sports' element={<Sports/>} />
<Route path='tech' element={<Technology/>} />
<Route path='fun' element={<Entertainment/>} />
</Routes>
</div>
</>
)
}
I am new here but a long time reader of StackOverflow content!
I am new to React and have a simple question about Multi-Pages App.
I did start to work on a website for a friend, I started with a one-pager but finally I did realize that I will need more then only one page. I installed react-router-dom and tried to set it up, the website doesn't return any errors, but only the SideBarMenu component is showing up !
the content of Home is not showing on / , same for the rest on /audio, /video, /images... And the weirdest part of it, if I write as URL for example some random thing like /asiomaos9j, it still show a blank website with the SideBarMenu without even crashing...
Anyone know why all my component on Home are not showing? Or even on /images the js file only contains a div with a H1 inside and this H1 not showing either... I can't figure out what I am doing wrong with this !
I did import as follow:
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
Then here is my App.js :
export default function App() {
return (
<React.StrictMode>
<Routes />
</React.StrictMode>
);
}
My Routes.js :
export default function Routes() {
return (
<Router>
<Switch>
<Route exact path='/' component={Home}></Route>
<Route exact path="/audio" component={AudioPlayerApp}></Route>
<Route exact path="/video" component={VideoPlayerApp}></Route>
<Route exact path="/images" component={ImagesApp}></Route>
</Switch>
<SideBarMenu pageWrapId={"page-wrap"} outerContainerId={"app"} />
</Router>
);
}
Finally as example, here is my Home.js
function Home(){
return(
<React.Fragment>
<Header />
<Services />
<ServicesContent />
<Media />
<MediaContent />
<Studio />
<StudioContent />
<Partenaires />
<PartenairesContent />
<Contact />
<ContactContent />
<Footer />
</React.Fragment>
)
}
export default Home;
Here as asked, SideBarMenu.js :
import React from 'react';
import { slide as Menu } from 'react-burger-menu';
import './components_css/SideBarMenu.css';
export default props =>{
return(
<Menu {...props}>
<a className="menu-item" href="#">
<span>+</span>Accueil
</a>
<a className="menu-item" href="#services_link">
<span>+</span>Services
</a>
<a className="menu-item" href="#media_link">
<span>+</span>Médias
</a>
<a className="menu-item" href="#studio_link">
<span>+</span>Studio
</a>
<a className="menu-item" href="#contact_link">
<span>+</span>Contact
</a>
</Menu>
);
};
These are links inside the Home page for the moment.
Take the exact out of the home route and place it at the end of all others
I have a MainPage that is loaded in App.js but when I use Browser Router and Route it will keep the MainPage and loads the second page over the top of it. Any tips would be helpful.
class App extends Component {
render() {
return(
<BrowserRouter>
<div className="App">
<Mainpage></Mainpage>
</div>
</BrowserRouter>
);
}
}
export default App;
The other thing that is weird is that it is loading the background of the page and styling that it is routing to when the button is not even pushed.
This is the main page.
class Mainpage extends Component {
render() {
return (
<div>
<header>
<nav>
<ul>
<li>
<Link exact to="/meettheteam">
This is a new Page
</Link>
</li>
</ul>
</nav>
</header>
<h1>
THE
<br />
BARBER
<br />
SHOP
</h1>
<p>
<img src={logo} alt="logo" />
<img src={facebookLogo} alt="logoFacebook" />
<img src={twitterLogo} alt="logoTwitter" />
#TheBarberShop
</p>
<ul>
<div className="schedule">
<li>SCHEDULE</li>
</div>
<div className="styles">
<li>STYLES</li>
</div>
<div className="meettheteam">
<li>MEET THE TEAM</li>
</div>
</ul>
<Switch>
<Route exact path="/meettheteam" component={MeetTheTeam} />
</Switch>
{/* <Route path="/stylesandprices" component={StylesAndPrices}/> */}
</div>
);
}
}
export default Mainpage;
Assuming you want the navigation portion of your main page to always render (to obviously allow navigation) then I have the following suggestions:
Move the header/nav to App component and render at the top of the router.
Move the Switch also to App and render your Mainpage and other page components in their own respective Route components, in decreasing specificity, i.e. "/pathA/b" listed before "/pathA".
Since the Switch matches and returns the first matching Route or Redirect, render the Mainpage route last as a default "home page".
If you want link highlighting (i.e. noticed the exact prop on the Link) then use NavLink as the Link component doesn't take this prop. Though, the exact prop here really only matters if you have nested routes that you don't want the link to appear active for
Changes
App
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<header>
<nav>
<ul>
<li>
<Link to="/meettheteam">
This is a new Page
</Link>
</li>
</ul>
</nav>
</header>
<Switch>
<Route path="/meettheteam" component={MeetTheTeam} />
<Route path="/stylesandprices" component={StylesAndPrices} />
{/* other routes listing in decreasing specificity */}
<Route component={Mainpage} />
</Switch>
</div>
</BrowserRouter>
);
}
}
Mainpage
class Mainpage extends Component {
render() {
return (
<div>
<h1>
THE
<br />
BARBER
<br />
SHOP
</h1>
<p>
<img src={logo} alt="logo" />
<img src={facebookLogo} alt="logoFacebook" />
<img src={twitterLogo} alt="logoTwitter" />
#TheBarberShop
</p>
<ul>
<div className="schedule">
<li>SCHEDULE</li>
</div>
<div className="styles">
<li>STYLES</li>
</div>
<div className="meettheteam">
<li>MEET THE TEAM</li>
</div>
</ul>
</div>
);
}
}
Routes should be wrapped inside of a <Switch> component of react-router-dom
Right usage:
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import ComponentA from './componenta'
import ComponentB from './componentb'
function App() {
return (
<Router>
<Switch>
<Route path="/">
<ComponentA />
</Route>
<Route path="/componentb">
<ComponentB />
</Route>
</Switch>
</Router>
);
}
export default App
This example below would render first route and second route on top of each other, This is the similar way on how the code snippets of the question was structured. The first route was wrap with Switch while the second route was outside of Switch
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import ComponentA from './componenta'
import ComponentB from './componentb'
function App() {
return (
<Router>
<Switch>
<Route path="/">
<ComponentA />
</Route>
</Switch>
<Route path="/">
<ComponentB />
</Route>
</Router>
);
}
export default App;
Tips/Suggestion:
The best thing to do is to wrap all the Route's with Switch statement at the top level of the app hierarchy
I'm trying to properly render my different components with the HTML/CSS sidebar with React Routes and Apollo.
I have a sidebar that correctly renders to the left of the screen and a little navbar on top of it, the space for the component is not being blocked by any css property.
The expected output is:
The actual output:
I've tried to place all the Routes inside the sidebar but every time I click on them, they don't load at all, the URL changes but the content doesn't and I need to reload the webpage for it take some effect. The help would be very much appreciated.
App.js
import React from 'react';
import ApolloClient from 'apollo-boost';
import {ApolloProvider} from '#apollo/react-hooks';
import { render } from 'react-dom';
import {BrowserRouter as Router, Route, Link,Switch} from 'react-router-dom';
import 'bootswatch/dist/flatly/bootstrap.min.css';
import Nav from './components/Nav'
import Home from './components/pages/Home'
import About from './components/pages/About'
import Articles from './components/article/Articles'
import Article from './components/article/Article'
const client = new ApolloClient({
uri: 'url in here'
});
const App = () => {
return (
<ApolloProvider client={client}>
<Router>
<div className="App">
<Nav/>
<Route exact path='/' component={Home} />
<Route exact path='/Articles' component={Articles} />
<Route exact path='/Articles/:id' component={Article} />
<Route exact path='/About' component={About} />
</div>
</Router>
</ApolloProvider>
);
}
render(<App />, document.getElementById('root'));
export default App;
Nav.js component
import React from 'react';
import {BrowserRouter as Link} from 'react-router-dom';
export default function Nav() {
return (
<div className="wrapper">
<nav id="sidebar">
<Link className="nav-link" to="/">
<h3>Home</h3>
</Link>
.
.
.
</nav>
<div id="content">
<nav className="navBar" >
</nav>
<div className ="ComponentRender">
Here's where the component should be rendered
</div>
</div>
</div>
)
}
I don't know about Apollo but I think you should move your routes from the App component to the Nav component, so the code would be:
App component:
const App = () => {
return (
<ApolloProvider client={client}>
<Router>
<div className="App">
<Nav/>
</div>
</Router>
</ApolloProvider>
);
}
And the Nav component:
export default function Nav() {
return (
<div className="wrapper">
<nav id="sidebar">
<Link className="nav-link" to="/">
<h3>Home</h3>
</Link>
.
.
.
</nav>
<div id="content">
<nav className="navBar" >
</nav>
<div className ="ComponentRender">
<Route exact path='/' component={Home} />
<Route exact path='/Articles' component={Articles} />
<Route exact path='/Articles/:id' component={Article} />
<Route exact path='/About' component={About} />
</div>
</div>
</div>
)
}
Don't forget to move imports from App to Nav as well.
In React(v16.13.1), The URL is changing but page is not loading.
I found the similar questions ReactJS - React Router not changing component but url is changing
and React Router URL Change but Not Component in stack and i tried from different ways but none helps me.
It may be a small mistake, Please help to rectify this.
My code follows:
App.js file
import React, { Component } from "react";
import { BrowserRouter as Router, Route,Switch,Redirect } from "react-router-dom";
import TopNav from "./components/Navbar/TopNav";
import SideNav from "./components/Navbar/SideNav";
import Dashboard from "./components/Dashboard";
import Analytics from "./components/Analytics";
import ToDo from "./components/ToDo";
class App extends React.Component {
render() {
return (
<div>
<TopNav />
<SideNav />
<Router>
<Switch>
<Route exact path="/">
<Dashboard />
</Route>
<Route exact path="/analytics">
<Analytics />
</Route>
{/* <Route exact path="/analytics" component={Analytics}></Route> */}
<Route exact path="/todo">
<ToDo />
</Route>
<Redirect to="/"></Redirect>
</Switch>
</Router>
</div>
);
}
}
export default App;
SideNav.js page as follows:
import React from "react";
import { BrowserRouter as Router, Link } from "react-router-dom";
class SideNav extends React.Component {
render() {
return (
<div className="sidebar-wrapper">
<div className="sidebar-container">
<Router>
<ul className="sidebar-menu">
<li className="active">
<i className="fa fa-cubes"></i>
<Link className="link" to="/">
Dashboard
</Link>
</li>
<li>
<i className="fa fa-pie-chart"></i>
<Link className="link" to="/analytics">
Analytics
</Link>
</li>
<li>
<i className="fa fa-medkit"></i>
<Link className="link" to="/todo">
What to do?
</Link>
</li>
</ul>
</Router>
</div>
</div>
);
}
}
export default SideNav;
Thanks in advance!
You only need one <Router> at top level of your app.
You are already using <Router> in your App component.
Wrap the SideNav component in the Router and remove the Router used in SideNav.
import React, { Component } from "react";
import {
BrowserRouter as Router,
Route,
Switch,
Redirect,
Link
} from "react-router-dom";
class SideNav extends Component {
render() {
return (
<div className="sidebar-wrapper">
<div className="sidebar-container">
{/* <Router> */}
<ul className="sidebar-menu">
<li className="active">
<i className="fa fa-cubes" />
<Link className="link" to="/">
Dashboard
</Link>
</li>
<li>
<i className="fa fa-pie-chart" />
<Link className="link" to="/analytics">
Analytics
</Link>
</li>
<li>
<i className="fa fa-medkit" />
<Link className="link" to="/todo">
What to do?
</Link>
</li>
</ul>
{/* </Router> */}
</div>
</div>
);
}
}
class App extends Component {
render() {
return (
<div>
<Router>
<SideNav />
<Switch>
<Route exact path="/">
<div>/</div>
</Route>
<Route exact path="/analytics">
<div>ana</div>
</Route>
<Route exact path="/todo">
<div>todo</div>
</Route>
<Redirect to="/" />
</Switch>
</Router>
</div>
);
}
}
export default App;
Your <SideNav /> and the main content are in seperate <Router />s. They don't see each other, and they can't work together.
Think, like two iframes navigaing independantly of each other, just without the actual iframes.
Everything that reqiures the router, basically your entire app, needs to be inside a single <Router />.
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom";
import TopNav from "./components/Navbar/TopNav";
import SideNav from "./components/Navbar/SideNav";
import Dashboard from "./components/Dashboard";
import Analytics from "./components/Analytics";
import ToDo from "./components/ToDo";
class App extends React.Component {
render() {
return (
<Router>
<TopNav />
<SideNav />
<Switch>
<Route exact path="/">
<Dashboard />
</Route>
<Route exact path="/analytics">
<Analytics />
</Route>
{/* <Route exact path="/analytics" component={Analytics}></Route> */}
<Route exact path="/todo">
<ToDo />
</Route>
<Redirect to="/"></Redirect>
</Switch>
</Router>
);
}
}
export default App;
SideNav.js
import React from "react";
import { BrowserRouter as Router, Link } from "react-router-dom";
class SideNav extends React.Component {
render() {
return (
<div className="sidebar-wrapper">
<div className="sidebar-container">
<ul className="sidebar-menu">
<li className="active">
<i className="fa fa-cubes"></i>
<Link className="link" to="/">
Dashboard
</Link>
</li>
<li>
<i className="fa fa-pie-chart"></i>
<Link className="link" to="/analytics">
Analytics
</Link>
</li>
<li>
<i className="fa fa-medkit"></i>
<Link className="link" to="/todo">
What to do?
</Link>
</li>
</ul>
</div>
</div>
);
}
}
The same applies for the TopNav.js.