I am very new to react-routing. After reading the docs and reading some articles this is how structured my routing. Please correct me if I am doing wrong.
Using react-router V4
Routes.js
import React from 'react';
import App from '../app/components/App';
import Dashboard from '../dashboard/components/Dashboard';
import Contact from '../dashboard/components/Contact';
import Account from '../dashboard/components/Account';
import Career from '../dashboard/components/Career';
import NoMatch from './NoMatch';
import { Provider } from 'react-redux';
import { Route, BrowserRouter, Switch, Redirect } from 'react-router-dom';
const Root = ({ store }) => (
<Provider store={store}>
<BrowserRouter>
<div>
<Route path="/app" component={App} />
<Switch>
<Route path="/app" exact component={Dashboard} />
<Route path="/app/home/dashboard" component={Dashboard} />
<Route path="/app/home/contact" component={Contact} />
<Route path="/app/home/account" component={Account} />
<Route path="/app/home/career" component={Career} />
<Route component={NoMatch} />
</Switch>
</div>
</BrowserRouter>
</Provider>
)
export default Root
I used /app 2 times. First is to load always as it has sidenav and header. Then inside switch I used to load default component dashboard.
App.js
import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import 'font-awesome/css/font-awesome.min.css';
import Header from './Header';
import SideNav from './SideNav';
class AppComp extends Component {
componentDidMount() {
const { match: { params } } = this.props;
}
render() {
return (
<div>
<div className="container body">
<div className="main_container">
<Header />
<SideNav routeparams={this.props}/>
</div>
</div>
</div>
);
}
}
export default AppComp;
Sidenav.jsx
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom'
import '../../css/sidenav.css';
class SideNav extends Component {
render() {
console.log(this.props.routeparams);
return (
<div className="col-md-3 left_col">
<div className="left_col">
<div className="clearfix"></div>
<div id="sidebar-menu">
<div className="menu">
<ul className="nav side-menu">
<li>
<NavLink to="/app/home/dashboard">Home</span></NavLink>
<ul>
<li className="current-page">
<NavLink to="/app/home/dashboard" activeClassName="current">Dashboard</NavLink>
</li>
<li>
<NavLink to="/app/home/contact" activeClassName="current">Contact</NavLink>
</li>
<li>
<NavLink to="/app/home/account" activeClassName="current">Account</NavLink>
</li>
<li>
<NavLink to="/app/home/career" activeClassName="current">Career</NavLink>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
);
}
}
export default SideNav;
I have two issue :
this.props.routeparams in sidenav logged twice which means sidenav rendered twice . this is happening after adding routing . Also this.props.routeparams match path is always /app, which I think because sidenav is a child component of app component. How can I fix this ? I want to get current route path in sidenav.
activeClassName="current" gets applied to correct navlink but the css style gets reflected only if I click somewhere in the page. Seems so strange. I can resolve that issue if I get current match.path at sidenav component then I will do it custom way without activeClassName.
Any help would be greatly appreciated.
Related
I'm working on converting a website from a static HTML/CSS/JS site into a React SPA and I want to use React Router for navigation. I installed Router into the correct directory, ran npm start from the correct directory, and my Terminal shows that everything compiled successfully, but my browser looks like this:
App.js file:
import React from 'react';
import './styles/App.css';
import Navbar from './components/Navbar';
class App extends React.Component {
render() {
return (
<div className = "App">
<div id ='container' className = 'container light'>
<Navbar />
</div>
</div>
)
}
}
export default App;
Navbar.js file:
import React, { Component } from 'react';
import '../styles/App.css';
import logo from '../img/logo.png'
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import App from '../App';
import About from './About';
import Portfolio from './Portfolio';
class Navbar extends Component {
render() {
return (
<Router>
<div className="Navbar">
<nav>
<ul className="navlist">
<Link to={App}>
<li className="active">Home</li>
</Link>
<Link to={About}>
<li>About Me</li>
</Link>
<Link to={App}>
<img className="brand" src={logo} alt="" />
</Link>
<Link to={Portfolio}>
<li>Portfolio</li>
</Link>
<li className="toggler"><span role="img" aria-label="dark moon">🌑</span></li>
</ul>
</nav>
<Switch>
<Route path= {About}>
<About />
</Route>
<Route path= {Portfolio}>
<Portfolio />
</Route>
<Route path= '{App}'>
<App />
</Route>
</Switch>
</div>
</Router>
)
}
}
export default Navbar;
About.JS
import React, { Component } from 'react';
import '../styles/App.css';
import Navbar from './Navbar'
class About extends Component {
render() {
return (
<div className="About">
<Navbar />
<h1>Hello World, This is the About Page</h1>
</div>
)
}
}
export default About;
Portfolio.JS
import React, { Component } from 'react';
import '../styles/App.css';
import Navbar from './Navbar'
class Portfolio extends Component {
render() {
return (
<div className="Portfolio">
<Navbar />
<h1>Hello World, This is the Portfolio Page</h1>
</div>
)
}
}
export default Portfolio;
I'm new to React and I'm not sure what I've done wrong. Happy to share any additional information needed.
That's not how Link is used, the to prop should have the path you want to navigate, and then you have to use the Route HOC with two options, pass the component as a child or in the component prop
Link
<Link to="/about">
About
</Link>
Route
<Route path="/about" component={About} />
<Route path="/about">
<About/>
</Route>
new to React Router, my question is how to render a particular component inside other layout which is already rendered (i have two components sidebar and content i just want if i click on any link in sidebar that component will we render in already render Content component not override that)
////////////Sidebar.js////////////
import React from 'react'
import { BrowserRouter, Link } from 'react-router-dom'
import PersonalImg from '../images/personal.gif'
const Sidebar = () => {
return (
<div className="sidebar">
<BrowserRouter>
<div className="personal-img">
<img src={PersonalImg} alt="personl-img" />
</div>
<div className="navigation">
<ul className="list">
<li><Link to="/about">About</Link></li>
<li><Link to="/work">Work</Link></li>
<li><Link to="/skills">Skills</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
</div>
</BrowserRouter>
</div>
)
}
export default Sidebar;
Content component...
/////////////////Content.js//////////////////
import React from 'react'
import { BrowserRouter, Route } from 'react-router-dom'
import About from './About'
import Skills from './Skills'
import Work from './Work'
import Contact from './Contact'
const Content = (props) => {
return (
<div className="content">
<BrowserRouter>
<Route path="/" componet={About} />
<Route path="/work" componet={Work} />
<Route path="/contact" componet={Contact} />
<Route path="/skills" componet={Skills} />
</BrowserRouter>
</div>
)
}
export default Content;
and thats how App.js rendering these components
render() {
return (
<Fragment>
<Sidebar />
<Content />
</Fragment>
)
}
Here, I have created small demo for you
https://codesandbox.io/s/naughty-glade-vnj0l
Problem 1: componet spell is wrong. It should be component in the Route.
Problem 2: set exact keyword for the first route like this <Route exact path="/" componet={About} />.
Use single BrowserRouter throughout the application.
I am a bit new to React.
I have a situation where I need to hide some navigation bar links in some components where as in the rest, I want to display them.
Actually been using react router V4 and typescript.
Need to hide page1 and page2 links when it comes to signup and login pages.
Say I also have a getstarted page that loads when the application is launched , here also I would like to hide the links.
Show the links in rest of the components.
Help would be appreciated
Router Code
import * as React from 'react';
import NavBar from './NavBar';
import SignUp from './SignUp';
import Page1 from './Page1';
import Page2 from './Page2';
import Login from './Login';
import GetStarted from './GetStarted';
import { BrowserRouter as Router , Switch , Route} from 'react-router-dom';
const NotFound = () => (
<div><h1>404.. This page is not found!</h1></div>
);
export default class App extends React.Component<{}, {}> {
render() {
return(
<Router>
<div className='container'>
<NavBar/>
<div className='body'>
<Switch>
<Route exact={true} path='/' component={GetStarted}/>
<Route path='/getstarted' component={GetStarted}/>
<Route path='/signup' component={SignUp}/>
<Route path='/login' component={Login}/>
<Route path='/page1' component={Page1}/>
<Route path='/page2' component={Page2}/>
<Route component={NotFound} />
</Switch>
</div>
</div>
</Router>
)
}
}
Navigation Bar Component
import React from 'react';
import { Link } from 'react-router-dom';
export default class NavBar extends React.Component<{}, {}> {
render() {
return (
<nav className="nav">
/*some logo will be displayed here followed by the links*/
<div className="container">
<ul className="item-wrapper">
<li>
<Link to="/page1">Link 1</Link>
</li>
<li>
<Link to="/page2">Link 2</Link>
</li>
</ul>
</div>
</nav>
);
}
}
Since you provide a login function, surely somewhere in your state you store the information whether a user is logged in or not. Use this state to determine whether to display the links:
import React from 'react';
import { Link } from 'react-router-dom';
export default class NavBar extends React.Component<{}, {}> {
render() {
return (
<nav className="nav">
<div className="container">
{user.loggedIn /* boolean indicating whether user is logged in */ &&
<ul className="item-wrapper">
<li>
<Link to="/page1">Link 1</Link>
</li>
<li>
<Link to="/page2">Link 2</Link>
</li>
</ul>
}
</div>
</nav>
);
}
}
i'm trying to implement router to my reactjs app and after setting things up, my page wont even load, it just keeps reloading in my browser till it crashs.
This is my app.js
import React, { Component } from "react";
import { BrowserRouter, Route } from "react-router-dom";
class App extends Component {
render() {
return (
<div className="App">
<Header />
<Content
job={this.state.header_infos[0].job}
college={this.state.header_infos[0].college}
/>
<Skills />
<Portfolio />
<Timeline />
<Footer />
<BrowserRouter>
<Route exact path="/" component={App} /> /* if it clicks in my logo, redirect to mainpage */
<Route path="/monitoria" component={Monitoria} /> /* if clicks in Monitoria from Navbar, redirects to Monitoria component. */
</BrowserRouter>
</div>
);
}
}
And this is my Header.js with my navbar
import React from "react";
import "../sass/Header.scss";
import { NavLink } from "react-router-dom";
const Header = () => {
return (
<header className="">
<NavLink exact to="/">
<h1 className="logo">Logo</h1>
</NavLink>
<input type="checkbox" id="nav-toggle" className="nav-toggle" />
<nav>
<ul>
<li className="menu-item">
<NavLink to="/monitoria">Monitoria</NavLink>
</li>
<a className="btn-rounded" href="#">
<li className="menu-item">Fale comigo</li>
</a>
</ul>
</nav>
<label htmlFor="nav-toggle" className="nav-toggle-label">
<span />
</label>
</header>
);
};
export default Header;
If i remove React Router DOM from my App.js my page works just fine. What i'm doing wrong?
As mentioned in comment, in app.js, you are assigning class App into a route that is contained in the App class.
My folder structure
reactdemo
|------------>public
|------------>src
|------->Component
|------->index.js
<-------------index.js------------>
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import ReactDOM from 'react-dom';
import Header from './Component/Header';
import Footer from './Component/Footer';
import Content from './Component/Content';
import About from './Component/about';
import Contact from './Component/Contact';
import JSON from './Component/db.json';
class App extends React.Component {
state = {
items:JSON
}
render() {
// console.log(this.state.items)
return (
<div>
<Header/>
<Content list={this.state.items} />
<Footer />
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('root'));
<---------Header Component------------->
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
//Component
import About from './about.js';
import Contact from './Contact.js';
class Header extends React.Component {
render() {
return (
<Router>
<div>
<nav className="navbar navbar-expand-sm bg-dark navbar-dark">
<ul className="navbar-nav">
<li className="nav-item">
<Link to="/">Home</Link>
</li>
<li className="nav-item">
<Link to="/about">About</Link>
</li>
<li className="nav-item">
<Link to="/contact">Contact</Link>
</li>
</ul>
</nav>
<Switch>
<Route path='/About' Component={About} />
<Route path='/Contact' Component={Contact} />
</Switch>
</div>
</Router>
);
}
}
export default Header;
<----------Content---------------->
import React from 'react';
const Content =(props) => {
console.log(props)
const test = props.list.map((list) => {
return (
<div key={list.id}>
<h4>{list.title}</h4>
<p>{list.feed}</p>
</div>
)
}
)
return (
<div>
{test}
</div>
)
}
export default Content;
<---------footer.js---------->
import React from 'react';
class Footer extends React.Component {
render() {
return (
<div className="text-center">
<p>Posted by: Hege Refsnes</p>
<p>Contact information: <a href="mailto:someone#example.com">
someone#example.com</a>.</p>
</div>
);
}
}
export default Footer;
<---------about---------->
import React, { Component } from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
class About extends Component {
render() {
return (
<div>
<h2>About</h2>
</div>
);
}
}
export default About;
<------------Contact---------->
import React, { Component } from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
class Contact extends Component {
render() {
return (
<div>
<h2>Contact</h2>
</div>
);
}
}
export default Contact;
<-----------End of Code-------->
I'm new to react and trying to implement react router. But I'm facing an issue- whenever I click on About and Contact link, the url changes in the browser, but the contents don't show in the browser. I have created separate contents for both "about" and "contact" inside the Components folder.Also, I'm using Sublime text 3 and using Babel for ES-6 as plugin but it's showing syntax error.I have also attached a screenshot for showing the issue
You write your component attribute with first letter uppercase, so Component should be component:
So instead of:
<Route path='/About' Component={About} />
<Route path='/Contact' Component={Contact} />
You should have:
<Route path='/About' component={About} />
<Route path='/Contact' component={Contact} />
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
//Component
import About from './about.js';
import Contact from './Contact.js';
class Header extends React.Component {
render() {
return (
<Router>
<div>
<nav className="navbar navbar-expand-sm bg-dark navbar-dark">
<ul className="navbar-nav">
<li className="nav-item">
<Link to="/">Home</Link>
</li>
<li className="nav-item">
<Link to="/about">About</Link>
</li>
<li className="nav-item">
<Link to="/contact">Contact</Link>
</li>
</ul>
</nav>
<Switch>
<Route path='/About' component={About} />
<Route path='/Contact' component={Contact} />
</Switch>
</div>
</Router>
);
}
}
export default Header;
It's not a deal breaker to use the path prop value to uppercase, because it's not case sensitive by default, but is recommended to have the <Route> path props the same you define on the <Link>, in case you have a prop like sensitive defined on the <Route> element.
In this case your final piece of code should look like this:
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
You can read more about this in the docs here.
the Link paths are defined as /about and /contact, where the Route paths are /About and /Contact, notice the uppercase first character and hence it doesn't match, also Route accepts a lower case component prop and not Component
<Router>
<div>
<nav className="navbar navbar-expand-sm bg-dark navbar-dark">
<ul className="navbar-nav">
<li className="nav-item">
<Link to="/">Home</Link>
</li>
<li className="nav-item">
<Link to="/about">About</Link>
</li>
<li className="nav-item">
<Link to="/contact">Contact</Link>
</li>
</ul>
</nav>
<Switch>
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
</Switch>
</div>
</Router>