I start learning about React, and I am working in an application in two parts: when the user is logged and is not.
When the user is not logged, the "/" will show the login page. When is logged, will show the Dashboard page. In Dashboard page, there is a top nav and a sidebar in the left, and in the "center" will show the content of the page. Linke in this image from iMaster:
SO the sidebar will have links, that will update the component that is shown as children of the Dashboard component. I searched about "Nested Routes", but no success.
I'm trying to do in this because I see that if I will show the navs in "all" pages, is better load the navs one time and then update the children os the navs, instead of loading the navs in every page.
Anyone can help?
App.js
import React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import Login from './pages/login';
import Dashboard from './pages/dashboard';
const App = () => (
<div className="App">
<BrowserRouter>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/dashboard" component={Dashboard} />
</Switch>
</BrowserRouter>
</div>
);
export default App;
Dashboard
import React, { Component } from 'react';
//BOOTSTRAP
import 'bootstrap/dist/css/bootstrap.min.css';
import { Col, Container, Row } from 'react-bootstrap';
//BOOTSTRAP
import './styles.css';
import TopSideNavBar from '../../components/TopSideNavBar';
export default class Dashboard extends Component {
render() {
return(
<>
<div className="body">
<TopSideNavBar />
<Container fluid className="content">
<Switch>
<Route path={`${match.path}/component1`} render={Component1}/>
<Route path={`${match.path}/component2`} render={Component2}/>
</switch>
</Container>
</div>
</>
);
}
}
Wrap your component with BrowserRouter and correct access to match.path
export default class Dashboard extends Component {
render() {
return (
<BrowserRouter>
<>
<div className="body">
<TopSideNavBar />
<Switch>
<Route path={`${this.props.match.path}/component1`} component={Component1} />
<Route path={`${this.props.match.path}/component2`} component={Component2} />
</Switch>
</div>
</>
</BrowserRouter>
);
}
}
Related
Hey I am a Smart Contract Developer first time using react and when I try to switch pages using Router both pages Data are showing on a single page, I wanna ask is there some way to first load main page and when I click on another button the data of another page show.
App.js:
<Router>
<Link className="btn-success user-btn" to = "/user">User Login</Link>
<Link className="btn-success admin-btn">Admin Login</Link>
<Switch>
<Route path={"/user"} exact>
<User />
</Route>
</Switch>
</Router>
User.js:
import React from 'react';
const User = () =>{
return(
<div>
User Panel
</div>
);
}
export default User;
App Component is the main component in React which acts as a container for all other components. When you put some content in there, it will show up everywhere in your app. You can simply create another component, let's name it Home
Home.js
import React from 'react';
import { Link } from 'react-router-dom';
const Home = () =>{
return(
<div>
<Link className="btn-success user-btn" to = "/user">User Login</Link>
<Link className="btn-success admin-btn">Admin Login</Link>
</div>
);
}
export default Home;
App.js
import User from './User';
import Home from './Home';
function App() {
return (
<div className="App">
<Router>
<Switch>
<Route exact path={"/"} component={Home}></Route>
<Route exact path={"/user"} component={User}></Route>
</Switch>
</Router>
</div>
);
}
export default App;
How to redirect from one class component to another class component/fresh page in ReactJS.
Currently, I am able to load new components through the link tags in react-router.
but then I want to redirect to another class component just like href in HTML to another fresh page where the previous states will not be available and it's a fresh new class.
Example:- I have 3 Pages
LandingPage
LoginPage
SignupPage
Initially, LandingPage will be opened and after that when I click the respective screen it will open.
How can i load a fresh LoginPage & SignupPage from LandingPage. Both SignupPage and LandingPage have a separate class component to manage the state of that particular screens.
Please share some code references.
Thanks in advance.. :)
If you want to open login or signup page from landing page you can simply call history.push('/login') from landing page component to open login page. history is available in every route so can be called directly.
index.js
import { BrowserRouter, Route,Switch} from 'react-router-dom';
import landingPage from './landingPage';
import login from './login';
import signup from './signup';
render(){
<BrowserRouter>
<Switch>
<Route exact={true} path="/" component={landingPage} />
<Route exact={true} path="/login" component={login} />
<Route exact={true} path="/signup" component={signup} />
</Switch>
</BrowserRouter>
}
//landing page component
landingPage =()=>{
const openLoginPage= () => {
history.push('/login'); //this will open login page on click of login button
}
return(<div>
< button onClick={openLoginPage}>login</button >
</div>)
}
Will it help to reach your idea? I just share you the idea of routing in react using react-router-dom
App.js
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch, Link } from "react-router-dom";
import SignUp from "./signUp";
import Login from "./login";
import Landing from "./landing";
class App extends Component {
render() {
return (
<Router>
<div id="container">
<div>
<Link to="/">Landing</Link>
<Link to="/signup">Sign Up</Link>
<Link to="/login">Login</Link>
</div>
<Switch>
<Route exact path="/signup" component={SignUp} />
<Route exact path="/login" component={Login} />
<Route exact path="/" component={Landing} />
</Switch>
</div>
</Router>
);
}
}
export default App;
You have supposedly created your functional component/ class component, you may import and use accordingly
Update for the class components
Once the routed from one component to another component each component will load with its own state and props
I have put here my class components, you have to make sure all App.js, landing.jsx, signUp.jsx and login.jsx are on the same folder location
landing.jsx
import React, { Component } from "react";
class Landing extends Component {
state={}
render() {
return (
<div>
<h1>Landing page</h1>
</div>
);
}
}
export default Landing;
signUp.jsx
import React, { Component } from "react";
class SignUp extends Component {
state={}
render() {
return (
<div>
<h1>Sign Up page</h1>
</div>
);
}
}
export default SignUp;
login.jsx
import React, { Component } from "react";
class Login extends Component {
state={}
render() {
return (
<div>
<h1>Login page</h1>
</div>
);
}
}
export default Login;
Another way is use push method on button click inside class components, and in both cases route should be there
<button onClick={()=> this.props.history.push('/')} ></button>
or
<button onClick={()=> this.props.history.push('/signup')} ></button>
I am building a consumer facing app with a admin dashboard. I want to keep the routing separate for them and so trying to delegate :-
App.js
import React, {Component} from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
//styles
import './style/bootstrap/bootstrap.scss';
//apps
import Mainapp from './mainapp/Mainapp';
import Admin from './admin/Admin';
const MainappContainer = () => (
<Mainapp />
);
const AdminContainer = () => (
<Admin />
);
class App extends Component{
render(){
return (
<Router>
<Switch>
<Route path="/admin" component={AdminContainer}/>
<Route path="/" component={MainappContainer}/>
</Switch>
</Router>
)
}
}
export default App;
Admin.js
import React, {Component} from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
//styles
import './admin-style.scss';
//layout
import ControlPanel from './component/layout/ControlPanel';
import Navbar from './component/layout/Navbar';
//pages
import Quote from './component/pages/quote/Quote';
class Admin extends Component{
render(){
return (
<div className="adminWrapper">
<ControlPanel />
<section className="viewPanel">
<Navbar />
<Router>
<Route path="/quote" component={Quote}/>
</Router>
</section>
</div>
)
}
}
export default Admin;
However when I hit the URL
http://localhost:3000/admin/quote
it doesn't seem to load the quote component
Quote.js
import React, { Component } from 'react';
class Quote extends Component {
render() {
return (
<div className="float-right pr-3">
<h3>
Quote Page
</h3>
</div>
)
}
}
export default Quote;
When dealing with nested subroutes, the easiest solution is to use match.
path - (string) The path pattern used to match. Useful for building nested
Routes.
url - (string) The matched portion of the URL. Useful for building
nested Links.
By design, components placed inside a Route's component render method are given several additional props from react-router-dom. Among them are history and match. You can leverage these props to either to match against sub routes and/or to control browser history location.
In addition, you only need one instance of BrowserRouter sitting at the top-level of the application, then you can use Switch to optionally render any main or sub routes. And you don't need to use class components unless you're utilizing state and/or a class field.
A very basic, rudimentary working example of your application:
src/components/Admin/index.js
import React from "react";
import { Switch, Link, Route } from "react-router-dom";
import ControlPanel from "../ControlPanel";
import Quote from "../Quote";
// since Admin is placed inside a Route's component render
// method, it has access to history and match
function Admin({ history, match }) {
return (
<div className="adminWrapper">
<ControlPanel />
<section className="viewPanel">
<Link to={`${match.url}/quote`}>View quote</Link>
<br />
<Switch>
<Route exact path={`${match.path}/quote`} component={Quote} />
</Switch>
</section>
<br />
<button type="button" onClick={() => history.goBack()}>
Go Back
</button>
</div>
);
}
export default Admin;
index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Link, Route, Switch } from "react-router-dom";
import Admin from "./components/Admin";
const linkStyle = {
padding: "0 10px"
};
function App() {
return (
<BrowserRouter>
<Link style={linkStyle} to="/">
Home
</Link>
<Link style={linkStyle} to="/admin">
Admin
</Link>
<Switch>
<Route path="/admin" component={Admin} />
<Route path="/" render={() => <h1>Main App</h1>} />
</Switch>
</BrowserRouter>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
Follow the Nested Routing Example
The main changes you need to do are:
1. Remove the <Router></Router> from Admin component and
2. Prepend match.path to "/quotes", like it is done in Topics component in the example. In the example, Topics is a function component so it is receiving match as function parameter. As your Admin component is class component, you can access it as this.props.match in render method.
<Route path={`${this.props.match.path}/quote`} component={Quote}/>
<Route exact path="/admin" component={AdminContainer}/>
<Route exact path="/admin/quote" component={Quote}/>
This won't route you to /admin/quote instead it will route you to /admin/admin/quote.
Since it is inside admin just /quote is enough
<Route path="/admin" component={AdminContainer}/>
<Route path="/quote" component={Quote}/>
It might sound weird but when i go to inner page from homepage i the hover on link hover effect works fine and goes to innerpage. then in innerpage I have a back button which returns back to Homepage and after coming back to Homepage, when I hover on the link, no Hover effect.
this is how i have called the inner pages, if it helps
import React from 'react';
import { Switch , Route , BrowserRouter } from 'react-router-dom';
import Training from './section/training';
function App() {
return (
<div className="main homepage">
<BrowserRouter>
<div>
<Switch>
<Route path="/training" component={Training} exact={true} />
</Switch>
</div>
</BrowserRouter>
</div>
);
}
export default App;
Update
This is a part of main_content.js in which i have used <Link>
<div className="portfolio-grid-img">
<Link to="/training">
<img src={training_thumb} alt="Training thumbnail" />
<div className="portfolio-grid-overlay">
<h3>Site Revamp</h3>
<p>Training Terminal</p>
</div>
</Link>
</div>
You will need a route to your home page component
import React from 'react';
import { Switch , Route , BrowserRouter } from 'react-router-dom';
import Training from './section/training';
import Home from './homePageContent';
function App() {
return (
<BrowserRouter>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/training" component={Training} exact={true} />
</Switch>
</BrowserRouter>
);
}
export default App;
I have Header and Footer components, which are used for surrounding internal pages.
I also have a Login component, which appears when the user is not logged in. This component doesn't implement Header or Footer components.
The problem is that I can't prevent Header and Footer components from being rendered with Login component. I can't exclude Login component to be rendered alone.
I tried Switch tag, but didn't get it to work.
import React, { Component } from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import { connect } from 'react-redux';
import * as actions from '../actions';
import Header from "./Header";
import Footer from "./Footer";
import Login from "./Login";
import manageCategories from "./manageCategories";
class App extends Component {
componentDidMount() {
this.props.fetchUser();
}
render() {
return (
<div>
<BrowserRouter>
<div>
<Route exact path="/login" component={Login} />
<Header />
<Route exact path="/manage-categories" component={manageCategories} />
<Footer />
</div>
</BrowserRouter>
</div>
);
}
}
export default connect(null, actions)(App);
You should add a new component that is parallel to the login component to contain the Header and Footer components.
<Route path="/home" component={Layout}/>
<Route exact path="/login" component={Login}/>
and the Layout:
render() {
return <div>
<Header />
<Route exact path={this.props.match.path} component={Home} />
<Route path={`${this.props.match.path}/manageCategories`} component={manageCategories} />
<Route path={`${this.props.match.path}/other`} component={otherComponent} />
<Footer />
</div>
}