React HashRouter not rendering other paths, only Rendering root component '/' - javascript

My Setup:
routes.js
const Router = () => (
<Switch>
<Route path="/" component={ Dashboard } />
<Route path="/somepath" component={ SomePath } />
</Switch>
);
index.js
<HashRouter>
<App />
</HashRouter>
app.js:
lass App extends Component {
render() {
return (
<div className="main-app">
<Header />
<div className="page__container">
<Router />
</div>
<Footer />
</div>
);
}
}
Issue is, when I navigate to localhost/#/ rootpath, it is correctly rendering Dashboard component as mentioned in routes.js file. But When I naviagte to localhost/#/somepath, it not rendering component for somepath, it is stil rendering / Component.
Even in React Devtool it shows <Route path="/"> is loaded, not <Route path="/somepath">

You may have to add exact to match the path. add exact prop to Route
<Route exact path="/somepath" component={ SomePath } />

Related

Why my components don't display on my React page?

So I'm learning React and building an app with multiple pages, I made a Routes file which looks like this:
import 'swiper/swiper.min.css';
import React from "react";
import { Route, Routes } from "react-router-dom";
import Home from "../pages/Home";
import Catalog from "../pages/Catalog";
import Detail from "../pages/Detail";
const Router = () => {
return (
<Routes>
<Route
path='/:category/search/:keyword'
component={Catalog}
/>
<Route
path='/:category/:id'
component={Detail}
/>
<Route
path='/:category'
component={Catalog}
/>
<Route
path='/'
exact
component={Home}
/>
</Routes>
);
}
And App.js looks like this:
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Header from './components/header/Header';
import Footer from './components/footer/Footer';
import Router from './config/Router';
function App() {
return (
<BrowserRouter>
<Routes>
<Route render={props =>{
<>
<Header {...props}/>
<Router/>
<Footer/>
</>
}}/>
</Routes>
</BrowserRouter>
);
}
export default App;
As you see, I have a browser router and Route which passes props to a component(as I understood) but for some reason the components don't display on the page(original components just have with their name inside of them, but they don't display in App.js).
And my console also says:
No routes matched location "/"
In routes.jsx file. I'm guessing it should lead to main page, but for some reason the route doesn't match and components in App.js don't display.
In Version 6.0.0 there is not any component prop in Route. It has been changed to element. So you need to change your Router to :
const Router = () => {
return (
<Routes>
<Route
path='/:category/search/:keyword'
element={Catalog}
/>
<Route
path='/:category/:id'
element={Detail}
/>
<Route
path='/:category'
element={Catalog}
/>
<Route
path='/'
exact
element={Home}
/>
</Routes>
);
}
As you've said you're using react-router-dom 6.0.2, and it seems that the tutorial you are following is for the older version (5?). There were some breaking changes in version 6.
You need to change your Router component to use element instead of component:
const Router = () => {
return (
<Routes>
<Route path="/:category/search/:keyword" element={<Catalog />} />
<Route path="/:category/:id" element={<Detail />} />
<Route path="/:category" element={<Catalog />} />
<Route path="/" exact element={<Home />} />
</Routes>
);
};
and also your App component seems to be getting in the way with the nested route.
I think it can be simplified to:
function App() {
return (
<BrowserRouter>
<>
<Header />
<Router />
<Footer />
</>
</BrowserRouter>
);
}
You can see a working demo on stackblitz

React: how to hide a component on certain pages

How do i hide certain components on certain pages in my app?
Specifically I need to hide Navbar and Header from the Settings page.
in App.js i set up a router:
<div>
<Router>
<Switch>
<Header/> <- header and navbar are here
<Navbar/>
<Route exact path = "/" component= { Data } />
<Route path = "/available-data" component= { Data } />
<Route path = "/devices" component= { Devices } />
<Route path = "/contacts" />
<Route path = "/chat" />
<Route path = "/settings" component = { Settings } /> <- i need to remove them from here
</Switch>
</Router>
</div>
Header and Navbar are used in every component except in Settings. How do i go about removing/hiding them?
All three of the files are function components with useState hooks(if they even have state) if it matters :)
You can render a second switcher component to only route to pages with the header and navbar UI.
// in App.js
<div>
<Router>
<Switch>
<Route exact path="/settings" component={Settings} />
<Route path='/' ><UiRouter /></Route>
</Switch>
</Router>
</div>
// in UiRouter.js
export default function UiRouter() {
return (
<>
<Header />
<Navbar />
<Switch>
<Route exact path="/" component={Data} />
<Route path="/available-data" component={Data} />
<Route path="/devices" component={Devices} />
<Route path="/contacts" component={Contacts}/>
<Route path="/chat" component={Chat}/>
</Switch>
</>
);
}
Also, as Ajith mentioned, you should not have the components that you want to render for each route (Header and Navbar) inside the Switch component.

React Router hierarchy with rendering components

I'm passing an object to a class component and want to have that component open in a different route. The routing works, but all the time the props are undefined in the child component unless I move the <Route path=''...> line before every other component. The props work, but the page display is not correct.
PARENT
import React, { Component } from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Header from "./Header";
import DarbaiLT from "./DarbaiLT";
import AnObject from "./AnObject";
let clickeddiv = ''
class App extends Component {
onObjectClick = (clickeddivffromdarbai) => {
clickeddiv = clickeddivffromdarbai;
console.log("clickeddiv: ", clickeddiv);
};
*//clickeddiv is data coming from DarbaiLT component*
};
render() {
return (
<Router>
<div>
<Switch>
<Route path="/object/:id" exact component={AnObject} />
<Route path="/about" exact component={About} />
<Route path="/contacts" exact component={Contacts} />
<Route path="/partners" exact component={Partneriai} />
<DarbaiLT onObjectClick={this.onObjectClick} />
<AnObject dataforComponent={clickeddiv}/> //when this line is the last, it's not working
</Switch>
<Footer />
</div>
</Router>
);
}
}
export default App;
CHILD
import React, { Component } from "react";
class AnObject extends Component {
constructor(props) {
super(props);
}
render() {
return (
<>
<div onClick={() => console.log(this.props.dataforComponent)}>
<img src='../smth/pic.jpg' width="100%" />
</div>
</>
);
}
}
export default AnObject;
if I move the line to the top, passing of props works, but then all pages show only the AnObject, and doesn't render the About, Contacts and so on...
<Router>
<div>
<Header />
<Slides />
<Switch>
<AnObject stateforyou={clickeddiv}/> //if the line is here, routing doesn't work
<Route path="/object/:id" exact component={AnObject} />
<Route path="/about" exact component={About} />
<Route path="/contacts" exact component={Contacts} />
<Route path="/partners" exact component={Partneriai} />
<DarbaiLT onObjectClick={this.onObjectClick} />
</Switch>
<Footer />
</div>
</Router>
the documentation of React Router states that: "All children of a < Switch > should be < Route >".
Using the react-router Switch is like using switch case statement of javascript, whenever the link is matched to the route, the passed component gets rendered. Your problem here, however, is how to pass props to the rendered component which is done this way:
<Switch>
<Route path="/object/:id" exact component={() => <AnObject stateforyou={clickeddiv}/> } />
<Route path="/about" exact component={About} />
<Route path="/contacts" exact component={Contacts} />
<Route path="/partners" exact component={Partneriai} />
</Switch>
I'm not sure I totally understand the issue. But when you use <Switch> in the react-router, it will render only the first match.
You have a switch set up like this:
<Switch>
<Route path="/about" exact component={About} />
<DarbaiLT onObjectClick={this.onObjectClick} />
<AnObject dataforComponent={clickeddiv}/>
</Switch>
This means that if the visitor is at the url /about, it will render only the About component and nothing else. If you want to be able to render multiple components simultaneously as siblings, remove the <Switch>...</Switch>.

Is there a best practice way to hide component using react router?

To hide the navbar on the home component I am doing the following
const NavbarComponent = (props) => {
console.log(props);
if (props.match.path === '/') {
return null;
} else
return (
it works fine, I need to have access to the router so I can send people to locations dependant on the props object , is there a better way to do it such that I have all router logic in the same place?
this is the current state of my router
return (
<div>
<Router>
<Route component={Navbar} />
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/api/:city/electronics" component={Electronics} />
<Route exact path="/api/:city/labour" component={Labour} />
<Route exact path="/api/posts/item/:id" component={ItemDetails} />
<Route exact path="/create/:city/:category" component={CreatePost} />
</Switch>
</Router>
</div>
);
thanks for your time.
I'm not sure I understand why your NavBar component is in it's own Route. Any components contained within the Router have access to the entire Router api, including Link - they do not need to be a Route to do so.
I would suggest wrapping all the Routes that include the NavBar with that component. The Routes will then be displayed as children of the Navbar component.
Here is a simplified example:
// App.js
return (
<div>
<Router>
<Switch>
<Route exact path="/" component={Home} />
<NavBar>
<Route exact path="/electronics" component={Electronics} />
<Route exact path="/labour" component={Labour} />
</NavBar>
</Switch>
</Router>
</div>
);
//NavBar.js
return (
<>
<div>
<Link to="/electronics">Electronics</Link>
<Link to="/labour">Labour</Link>
</div>
<div>{props.children}</div>
</>
);
codesandbox

Nested <Route> components are not rendering properly in react-redux-router [duplicate]

I am trying to group some of my routes together with React Router v4 to clean up some of my components. For now I just want to have my non logged in routes group together and my admin routes grouped together but the following doens't work.
main.js
const Main = () => {
return (
<main>
<Switch>
<Route exact path='/' component={Public} />
<Route path='/admin' component={Admin} />
</Switch>
</main>
);
};
export default Main;
public.js
const Public = () => {
return (
<Switch>
<Route exact path='/' component={Greeting} />
<Route path='/signup' component={SignupPage} />
<Route path='/login' component={LoginPage} />
</Switch>
);
};
export default Public;
The Greeting component shows at "localhost:3000/", but the SignupPage component does not show at "localhost:3000/signup" and the Login component doesn't show at "localhost:3000/signup". Looking at the React Dev Tools these two routes return Null.
The reason is very obvious. for your route in main.js, you have specified the Route path of Public component with exact exact path='/' and then in the Public component you are matching for the other Routes. So if the route path is /signup, at first the path is not exact so Public component is not rendered and hence no subRoutes will.
Change your route configuration to the following
main.js
const Main = () => {
return (
<main>
<Switch>
<Route path='/' component={Public} />
<Route path='/admin' component={Admin} />
</Switch>
</main>
);
};
export default Main
public.js
const Public = () => {
return (
<Switch>
<Route exact path='/' component={Greeting} />
<Route path='/signup' component={SignupPage} />
<Route path='/login' component={LoginPage} />
</Switch>
);
};
Also when you are specifying the nested routes these should be relative to the parent Route, for instance if the parent route is /home and then in the child Route you wish to write /dashboard . It should be written like
<Route path="/home/dashboard" component={Dashboard}
or even better
<Route path={`${this.props.match.path}/dashboard`} component={Dashboard}

Categories

Resources