Basically, I am learning React Routing with react-router-dom, version 5.0.0 and I have some components like Home, About, Contact etc. and I am trying to change each component by clicking on NavLink but not changing components just changing URL
Indexjs:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import './Style.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import Header from "./components/Header";
import Footer from "./components/Footer";
import Web from "./Web";
ReactDOM.render(
<React.Fragment>
<Header />
<Web />
<Footer />
</React.Fragment>
, document.getElementById('root'));
serviceWorker.register();
Web Componet:
import React, {Component} from 'react';
import {BrowserRouter as Router, Route, Link, NavLink, Redirect, Switch,withRouter} from "react-router-dom";
//import Route from 'react-router-dom/Route';
import {Home} from "./components/Home";
import {About} from "./components/About";
import {Contact} from "./components/Contact";
import {Products} from "./components/Products";
class Web extends Component {
render() {
return (
<Router>
<Switch>
<Route path={"/"} exact component={withRouter(Home)}/>
<Route path={"/products"} component={withRouter(Products)}/>
<Route path={"/about"} component={About}/>
<Route path={"/contact"} component={Contact}/>
<Route path={"/something"} render={
() => {
return (<h1>This is something page</h1>);
}
}/>
</Switch>
</Router>
);
}
}
export default Web;
Header Component:
import React, { Component } from 'react';
import logo from '../logo.jpg';
import {BrowserRouter as Router, Route, Link, NavLink, Redirect} from "react-router-dom";
class Header extends Component {
render() {
return(
<Router>
<header className={'header_area'}>
<div className="container">
<div className="logo">
<img src={logo} alt="logo"/>
</div>
<nav className={'main_nav'}>
<ul>
<li><NavLink to="/" activeStyle={{color:"green"}} exact>Home</NavLink></li>
<li><NavLink to="/products" activeStyle={{color:"green"}} exact>Products</NavLink></li>
<li><NavLink to="/about" activeStyle={{color:"green"}} exact>About</NavLink></li>
<li><NavLink to="/contact" activeStyle={{color:"green"}} exact>Contact</NavLink></li>
</ul>
</nav>
<div className="float_clear"></div>
</div>
</header>
</Router>
);
}
}
export default Header;
Home Component:
import React from 'react';
export class Home extends React.Component {
render() {
return (
<React.Fragment>
<article className={'article_area'}>
<div className="container article">
<h2>Home</h2>
</div>
</article>
</React.Fragment>
);
}
}
About Component:
import React from 'react';
export class About extends React.Component {
render() {
return (
<React.Fragment>
<article className={'article_area'}>
<div className="container article">
<h2>About us</h2>
</div>
</article>
</React.Fragment>
);
}
}
Can anyone help me?
You should use a single Router and all of your routes and links should have it as one of their parents.
Change your index:
<React.Fragment>
<Router>
<Header />
<Web />
<Footer />
</Router>
</React.Fragment>
and remove other <Router>s
Also you do not need to use withRouter for components inside Route. They will get react-router props directly.
Related
This question already has an answer here:
React Route render blank page
(1 answer)
Closed 4 months ago.
I was trying to create simple navbar where onclick will redirect to component but unable to redirect to the page.
Like if I click on dogs it should be redirected to home component i have given component navbar where link to dogs is available.
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
Navbar.js
import React, { useState } from "react";
import { Link } from "react-router-dom";
import Home from "./Home";
import Select from "./Select";
function Navbar({ props }) {
return (
<div className="navbar">
<li>
<Link to="/">Dogs</Link>
</li>
<li>
<Link to="/cats">Cats</Link>
</li>
<li>
<Link to="/sheeps">Sheeps</Link>
</li>
<li>
<Link to="/goats">Goats</Link>
</li>
</div>
);
}
export default Navbar;
Home.js
import React from "react";
function Home() {
return (
<div>
<h3>Dogs</h3>
<div>
<img src="./dog.png"/>
<img src="./dog.png"/>
</div>
</div>
);
}
export default Home;
App.js
import "./App.css";
import Navbar from "./Components/Navbar";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Home from "./Components/Home";
import Select from "./Components/Select";
function App() {
return (
<div className="App">
<Router>
<Navbar />
<Routes>
<Route exact path="/" component={<Home />} />
<Route path="/cats" component={<Select />} />
</Routes>
</Router>
</div>
);
}
export default App;
In new versions of react-router-dom you should use "element" instead of "component"
like:
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/cats" element={<Select />} />
</Routes>
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>
I have a homepage with a link to a form, like this:
import React, { Component } from 'react';
import {
BrowserRouter as Router,
Route,
NavLink,
Redirect,
Switch,
withRouter
} from "react-router-dom";
import addHand from './Forms/addHand'
export class Home extends Component {
render() {
return (
<div>
<Router>
<div>
<NavLink to= '/hands/new'> Add a new hand </NavLink>
<Route path= '/hands/new' component={addHand}/>
<h4> Search For Hands By Category </h4>
<h4> Search For Sessions By Category </h4>
<h4> Search For Tables By Category </h4>
</div>
</Router>
</div>
);
}
}
export default Home;
I also have a navbar with a link to go home from any page, like this:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { NavLink } from 'react-router-dom';
import unmountComponentAtNode from 'react-dom';
class NavBar extends Component {
render() {
return (
<div className="navbar">
<NavLink className="link"
to="/"
exact
>Home</NavLink>
</div>
);
}
};
export default NavBar;
If I go to the form, then change my mind and decide I want to go back to the homepage, the url changes when I press the navlink, but the form is still rendered on the homepage. I can keep going back and forth between routes, but the only way to get the form to unmount from the DOM is to refresh the page. What causes this behavior, and what can I do to fix it? I have experienced similar issues before in React but have never found the solution. Thanks!
Edit** I tried adding this to the navlink:
render() {
const refCallback = node => {
unmountComponentAtNode(node)
}
return (
<div className="navbar">
<NavLink className="link"
to="/"
exact
innerRef={refCallback}
>Home</NavLink>
</div>
);
}
};
as per the react router docs, but it gives me this error:
unmountComponentAtNode(...): Target container is not a DOM element.
Here is the code in app.js
import React, { Component } from 'react';
import './App.css';
import { Router, Route } from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
import Home from './Components/Home'
import Navbar from './Components/Navbar';
import addHand from './Components/Forms/addHand';
export const history = createBrowserHistory();
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title-top">Hi Adam, welcome to your Personal
Poker Universe!</h1>
<h1 className="App-title-middle">Not Adam? GTFO!</h1>
<h1 className="App-title-bottom">Just Kidding, you can stay</h1>
</header>
<Router history= {history}>
<div>
<Navbar/>
<Route exact path='/' component= {Home} />
</div>
</Router>
</div>
);
}
}
export default App;
Define one Router in your App.js:
<Router history={history}>
<Switch>
<Route exact path="/" component={Home} />} />
<Route path="/hands/new" component={addHand} />
</Switch>
</Router>
then try navigating between routes it should work. Please Let me know if it doesn't work
I want to create a page in such a way that it will route in such a way....... that
App.js to HomePage.js to Footer.js. Now when I try to perform this task it shows error that Router has only 1 child element.
Code for App.js:
import React, { Component } from 'react';
import logo from './logo.svg';
import HomePage from './Home_page'
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<HomePage />
</div>
);
}
}
export default App;
Code for Home_page.js
import React, {Component} from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import FooterPage from './FooterPage';
class HomePage extends Component {
render(){
return(
<Router>
<div>
<Link to='./FooterPage'>Footer Page</Link>
</div>
<Switch>
<Route exact path='./FooterPage' component={FooterPage} />
</Switch>
</Router>
);
}
}
export default HomePage;
Code for Footer.js
import React, {Component} from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
class FooterPage extends Component {
render(){
return(
<div>
</div>
);
}
}
export default FooterPage;
At your Home_Page.js
import React, {Component} from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import FooterPage from './FooterPage';
class HomePage extends Component {
render(){
return(
<Router>
<div>
<div>
<Link to='./FooterPage'>Footer Page</Link>
</div>
<Switch>
<Route exact path='./FooterPage' component={FooterPage} />
</Switch>
</div>
</Router>
);
}
}
export default HomePage;
here you have only one child inside Route, not two. See https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/BrowserRouter.md
I'm working on a small react app with four components: Main, Nav, Timer, and Countdown. When I run it (open a new tab and load the app, not refresh), I want this app to render Main and Timer components simultaneously, but the app only renders Main Component and I see a blank page with only Nav component has been rendered.
I tried using IndexRoute but I got a strange error and it didn't work for me.
Here's my code:
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter as Router, Route, IndexRoute, hashHistory} from 'react-router-dom';
import Main from 'Main';
import Timer from 'Timer';
import Countdown from 'Countdown';
ReactDOM.render(
<Router history={hashHistory}>
<div>
<Route path="/" component={Main} />
<Route exact path="/timer" component={Timer} />
<Route path="/countdown" component={Countdown} />
</div>
</Router>,
document.getElementById('app')
);
Main Component:
import React, {Component} from 'react';
import Nav from 'Nav';
class Main extends Component {
render() {
return (
<Nav />
);
}
}
export default Main;
Nav Component:
import React, {Component} from 'react';
import {NavLink} from 'react-router-dom';
class Nav extends Component {
render() {
return (
<div className="top-bar">
<div className="top-bar-left">
<ul className="menu">
<li className="menu-text">React Timer</li>
<li><NavLink to="/timer" activeClassName="active-link" activeStyle={{fontWeight: 'bold'}}>Timer</NavLink></li>
<li><NavLink to="/countdown" activeClassName="active-link" activeStyle={{fontWeight: 'bold'}}>Countdown</NavLink></li>
</ul>
</div>
<div className="top-bar-right">
<ul className="menu">
<li className="menu-text">Created by Milad Fattahi</li>
</ul>
</div>
</div>
);
}
}
export default Nav;
The other two components contain only a simple text element.
IndexRoute and hashHistory are not available in react-router-dom. Make use of Switch to render only first matching Route. You can then have the Child Routes in the component itself.
Also when you use Switch , have the route with path="/" at last otherwise it will match it at the begining and will not render your other routes
You can configure your time component to be a child of the Main component like
import {BrowserRouter as Router, Route} from 'react-router-dom';
ReactDOM.render(
<Router>
<Switch>
<Route path="/" component={Main} />
</Switch>
</Router>,
document.getElementById('app')
);
Then in Main component
import React, {Component} from 'react';
import Nav from 'Nav';
import {Route, Redirect} from 'react-router-dom'
class Main extends Component {
render() {
return (
<div>
<Nav />
<Redirect to="/timer" />
<Route exact path="/timer" component={Timer} />
<Route path="/countdown" component={Countdown} />
</div>
);
}
}
export default Main;