I am new to React and I am trying to create a sidebar having links to different pages or modules. I have everything modularized meaning, the sidebar Navigation is a separate module where I import all the linked classes and then use react-router-dom to redirect the paths. But somehow when redirecting, The response page is blank.
Navigation Module:
import React, { Component } from "react";
import { Route, Switch, Link } from "react-router-dom";
import Colors from "../../pages/Colors";
import Typography from "../../pages/Typography";
import Spaces from "../../pages/Spaces";
import Buttons from "../../pages/Buttons";
import Inputs from "../../pages/Inputs";
import Grid from "../../pages/Grid";
import "./style.css";
class Nav extends Component {
render() {
return (
<div className="nav">
<ul>
<li>
<Link to="/colors">Colors</Link>
</li>
<li>
<Link to="/typography">Typography</Link>
</li>
<li>
<Link to="/spaces">Spaces</Link>
</li>
<li>
<Link to="/buttons">Buttons</Link>
</li>
<li>
<Link to="/inputs">Inputs</Link>
</li>
<li>
<Link to="/grid">Grid</Link>
</li>
</ul>
<Switch>
<Route path="/colors" component={Colors} exact />
<Route path="/typography" component={Typography} exact />
<Route path="/spaces" component={Spaces} exact />
<Route path="/buttons" component={Buttons} exact />
<Route path="/inputs" component={Inputs} exact />
<Route path="/grid" component={Grid} exact />
</Switch>
</div>
);
}
}
export default Nav;
Now the link classes that I import here have just simple content right now like the following.
pages/Colors/index.js:
import React, { Component } from "react";
class Colors extends Component {
render() {
return (
<div>
<h1>Colors</h1>
</div>
);
}
}
export default Colors;
The main BrowserRouter is located in the App.js component from where the Sidebar component is called having Navigation component.
Now the thing is if I remove the BrowserRouter from App.js and put it in the Navigation module the routing works.
How come so?
Which pattern is the correct one?
When you work with React-router and React-router-dom, make sure the Router component is the top most parent.
You can try again by:
Move all Router, Switch into App.js.
Inside Sidebar component, just render links, neither Switch nor Route component.
It will work.
Similar to the answer from Shina, who covers it pretty well, just a few more comments. Keeping your React-Router and switch in your App.jsx file is relatively standard. Since App is the parent component, the Router and Switch will only be rendered once, while keeping the router in Nav.jsx would force the Switch re-rendered with each route. But keeping the Switch wrapped in the Router component should solve your issues here.
Related
I am creating a simple react project. I created an addStudent page. When I go through the link (../add), All components reload including Navbar. I want to reload only addStudent page without reloading Navbar. Can anyone help me?.
App.js
import React from "react";
import Header from "./components/header";
import AddStudent from "./components/addStudent";
import { BrowserRouter as Router, Route } from 'react-router-dom';
function App() {
return (
<Router>
<div>
<Header />
<Route path="/add" component={AddStudent} />
</div>
</Router>
);
}
export default App;
I want to connect my sidebar to dashboard. Everytime I click on an icon in the sidebar I want to sidebar to stays the same but dashboard to change. https://imgur.com/1hwNlNr I am having a problem with the rendering. When I click on the Sound Icon Sidebar does not stay as you can see https://imgur.com/YjLmhLh
import React from 'react'
import './SystemSidebar.css'
import SoundIcon from '#material-ui/icons/Computer';
import ComputerIcon from '#material-ui/icons/Computer';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';
import Sound from './Sound';
import Computer from './Computer;
const SystemSidebar=()=> {
return (
<div className='system'>
<div className="sidebar">
<Link to='Sound'><VolumeUpIcon /></Link>
<h4> Sound</h4>
<Link to='Computer'><ComputerIcon /></Link>
<h4> Computer</h4>
</div>
</div>
import React,{Component} from 'react'
import Sound from './Sound';
import Computer from './Computer';
import SystemSidebar from './SystemSidebar';
class MainSystem extends Component {
render(){
return (
<div className="MAIN">
<BrowserRouter>
<SystemSidebar />
<Switch>
<Route exact path="/" component={SystemSidebar} />
<Route exact path="/Sound" component={Sound}/>
<Route exact path="/Computer" component={Computer}/>
</Switch>
</BrowserRouter>
</div>
);
}
}
Did you post the code from two separate .js files into this code block? Your SystemSidebar function is missing some closing parenthesis/brackets and this code has multiple duplicate imports/incorrect paths if all this code lives in the same file.
Other than that, you're rendering SystemSidebar twice when at the root URL. You want a component for some type of home/welcome page at this route, not the sidebar:
<Route exact path="/" component={SystemSidebar} />
Please post complete code in separate code blocks if the code is in separate files.
I am making a landing page for my site, which will have 3 components - header, main and footer, only for the landing page. The header component is just a nav bar with a logo on the left and sign in button on the right.
When the sign in button is clicked, I render a login route using the router but the problem is the previous components of Landing page (Header, Main and Landing) are also rendered with the new routed Login component.
Here's my App.js file where Landing is inserted.
import React, {Component} from 'react';
import Landing from './components/Landing/Landing';
class App extends Component {
render() {
return (
<div className="App">
<Landing/>
</div>
);
}
}
export default App;
and in Landing component I have this setup:
import React, {Component} from 'react';
import Header from './Header';
import Main from './Main';
import Footer from './Footer'
class Landing extends Component {
render() {
return (
<div className="container__landing">
<Header/>
<Main/>
<Footer/>
</div>
);
}
}
export default Landing;
Here's my header component, for brevity I have left out the other two components:
import React, {Component} from 'react';
import {BrowserRouter as Router, Link} from 'react-router-dom';
import {Route, Switch} from 'react-router';
import Login from '../auth/Login';
class Header extends Component {
render() {
return (
<Router>
<header className="header">
<div className="header__nav">
<p>STRONG LIVE</p>
<button className="sign_in">
<Link to="/login">
Sign In
</Link>
</button>
</div>
<Route exact path="/login" component={Login}/>
</header>
</Router>
)
}
}
export default Header;
The login component is rendered but it's placed inside the landing component along with the header and other present components.
I want the login page to be stand-alone and without the header, which is currently above it.
I have seen some tutorial where they have used the props.history.push('/path) but in React Dev Tools, none of my components have these props.
How do I switch components on button click? Thank you.
When the URL will match the path property of your <Route> component, a.k.a. when you'll be on the /login page, React router will render your <Login> component at the place in your component tree where the corresponding <Route> is.
The problem is that your <Router>, and more specifically your login <Route> are inside the <Landing> component.
If you want the login page to be rendered without header, you should place both the <Landing> and <Login> components inside a <Route>, next to each other. Then, render them conditionally using React Router's <Switch>component :
A <Switch> will iterate over all of its children elements and only render the first one that matches the current location. (see the documentation for details)
Here's an (untested) example :
class App extends Component {
render() {
return (
<div className="App">
<Router>
<Switch>
{/* Render the login component alone if we're on /login */}
<Route exact path="/login" component={Login} />
{/* Otherwise, render the Landing component */}
<Route component={Landing} />
</Switch>
</Router>
</div>
);
}
}
I'm using react.js and react router to render components on a certain route. In development all of my components show up, but in production on heroku my components render underneath each other, despite adding a z-index property. For example, The navbar and the home page is a component. This is a picture of the project in development. Everything shows up. The navbar has a z-index that is above all.
Now when i pushed this project to production the navbar was rendered underneath the home component.
I hope this question is clear, but i'm unsure why the component is rendered underneath.
Here is my app.js
import React, { Component } from 'react';
import Nav from './nav'
import Home from './Home'
import About from './About'
import Gallery from './Gallery'
import Resume from './Resume'
import {Route, Router, BrowserRouter, withRouter } from 'react-router-dom'
export default class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Nav/>
<Route exact path='/' component={Home}/>
<Route exact path='/about' component={About}/>
<Route exact path='/gallery' component={Gallery}/>
<Route exact path='/resume' component={Resume}/>
</div>
</BrowserRouter>
);
}
}
So I am very new to React and react routing so forgive me if this is simple. I have seen similar questions asked but not quite what I was looking for or I didnt understand it enough to figure it out.
Question: How do I get routing to jump to the page? It changes in the URL but seemingly no change. (localhost:8080/#/listings?_k=26kljm) is the same as localhost:8080/
Anyway here is what I have
main.js
import React from "react";
import ReactDOM from "react-dom";
import { Router, Route, IndexRoute, hashHistory } from "react-router";
import Layout from "./components/Layout";
import Listing from "./components/pages/Listings";
import NoMatch from "./components/partials/NoMatch";
const app = document.getElementById('app');
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={Layout}>
<Route path="/listings" name="listings" component={Listing}></Route>
</Route>
</Router>,
app);
Layout.js
import React from "react";
import Footer from "./partials/Footer";
import Body from "./pages/Index";
import Header from "./partials/Header";
export default class Layout extends React.Component {
render() {
return (
<div>
<Header/>
<Body />
<Footer />
</div>
);
}
}
Header.js
This one is long so ill spare you but you should know there is a link
<Link to="/listings">Listings</Link>
And finally
Listings.js
import React from "react";
import Header from "../partials/Header";
import Footer from "../partials/Footer";
export default class Listings extends React.Component {
render(){
return(
<div>
<Header />
<div class="row">
<div class="col-md-8">
<h1>THIS SHOULD BE HERE</h1>
</div>
</div>
<Footer />
</div>
);
}
}
I feel like I am missing something small or I dont have a good grasp on components.
To Note: I just noticed in the source the Link created an href like this
Listings
Why is the extra hash there!?
I get a Cannot GET /listings if I go directly to localhost:8080/listings
At first sight, I cannot find any mistake in your code. But I would recommend you to check out the react router examples which will fit perfect to your case:
https://github.com/reactjs/react-router
Just clone this repo, run npm install and npm start. Then you can browse through the examples within the URL http:localhost:8080.
When you take a look at the "Active Links" example, you will notice that it shows exactly what you want (except HashHistory, but you can add this manually without much work).
Hope this helps.
Many greetings
So the problem was with how I was understanding components.
The key here is {this.props.children}
By changing Layout.js too:
export default class Layout extends React.Component {
render() {
return (
<div>
<Header/>
{this.props.children}
<Footer />
</div>
);
}
}
main.js
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={Layout}>
<IndexRoute component={Index}></IndexRoute>
<Route path="/listings" name="listings" component={Listing}></Route>
</Route>
</Router>,
app);
The makes routing work correctly