When I set up React Router Dom and changed through routes, Routes keep adding Infront.
Example:- If I'm on the http://localhost:3001/login page and I click to Register Link register route is added in front like this ==> http://localhost:3001/login/register
Can anyone show me what have I done wrong?
Codes
App.js
import "./App.scss";
import { Routes, Switch, Route } from "react-router-dom";
import Home from "./components/Home/Home";
import Login from "./components/Login/Login";
import Register from "./components/Register/Register";
function App() {
return (
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
</Routes>
);
}
export default App;
Home.js
import React from "react";
import { Link, Router } from "react-router-dom";
function Home() {
return (
<div>
Home
<ul>
<li>
<Link to="login">Login</Link>
</li>
<li>
<Link to="register">Register</Link>
</li>
</ul>
</div>
);
}
export default Home;
Register.js
import React from "react";
import { Link, Router } from "react-router-dom";
function Register() {
return (
<div>
Register
<ul>
<li>
<Link to="login">Login</Link>
</li>
</ul>
</div>
);
}
export default Register;
Login.js
import React from "react";
import { Link, Router } from "react-router-dom";
function Login() {
return (
<div>
Login
<ul>
<li>
<Link to="register">Register</Link>
</li>
</ul>
</div>
);
}
export default Login;
Issue
react-router-dom#6 uses both absolute and relative path routing/navigation. The difference between absolute and relative routing/navigation is a leading "/" character in paths/targets.
For example, the Login component is rendered on path="/login" and renders a link <Link to="register">Register</Link> to "register". This means that Login will link to a "register" path relative to the current "/login" path, resulting in navigating to "/login/register".
The same issue occurs when rendering Register on path="/register" and rendering <Link to="login">Login</Link>.
Solution
Use absolute paths:
Example:
function Register() {
return (
<div>
Register
<ul>
<li>
<Link to="/login">Login</Link>
</li>
</ul>
</div>
);
}
...
function Login() {
return (
<div>
Login
<ul>
<li>
<Link to="/register">Register</Link>
</li>
</ul>
</div>
);
}
Use relative paths and navigate to a sibling route (i.e. a sibling route rendered by the same parent Routes component).
Example:
function Register() {
return (
<div>
Register
<ul>
<li>
<Link to="../login">Login</Link>
</li>
</ul>
</div>
);
}
...
function Login() {
return (
<div>
Login
<ul>
<li>
<Link to="../register">Register</Link>
</li>
</ul>
</div>
);
}
I believe, that changing the Link to parameter to contain / (slash) at the beggining, should solve your problem. Final elem should look like this: <Link to="/register">Register</Link>
Related
when i use link on my navbar component it changes the url but does not change the component, but it changes component when i reload,when i put link in main app.js it routes perfectly
app.js
import './App.css';
import Navbar from './Navbar/Navbar'
import About from './About/About'
import { Route, Link, BrowserRouter as Router ,Switch} from 'react-router-dom'
function App() {
return (
<div>
<Navbar/>
<Router>
<Link to="/about">about</Link>
<Switch>
<Route exact path="/about">
<About/>
</Route>
</Switch>
</Router>
</div>
);
}
export default App;
navbar.js
import React from 'react'
import './Navbar.css'
import { Link, Router, BrowserRouter} from 'react-router-dom';
function Navbar() {
return (
<div>
<nav className="navbar">
<div>
<h1 className="nav_text">ExportGrains</h1>
</div>
<ul className="nav_ul">
<BrowserRouter>
<Link to="/about">about</Link>
<li id="nav_li">HOME</li>
<li id="nav_li">PRODUCTS</li>
<li id="nav_li">ABOUT</li>
<li id="nav_li">CONTACT</li>
</BrowserRouter>
</ul>
</nav>
</div>
)
}
export default Navbar
about.js
import React from 'react'
function About() {
return (
<div>
<h1>about page</h1>
</div>
)
}
export default About;
it would be very kind if you can help me with it
It should be
import About from "...."
....
....
<Route path="/about" exact component={About} />
You should use one single Router for all your routes. The problem is that navbar is using different router and your other components are inside another router. So remove the router inside navbar and use single router inside your app component.
Also you can add Navbar as default route and put it at the end of the switch so that it matches when none of the above routes are matching.
function App() {
return (
<Router>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/">
<Navbar />
</Route>
</Switch>
</Router>
);
}
Switch renders the first child <Route> or <Redirect> that matches the
location.
function Navbar() {
return (
<div>
<nav className="navbar">
<div>
<h1 className="nav_text">ExportGrains</h1>
</div>
<ul className="nav_ul">
<Link to="/about">about</Link>
<li id="nav_li">HOME</li>
<li id="nav_li">PRODUCTS</li>
<li id="nav_li">ABOUT</li>
<li id="nav_li">CONTACT</li>
</ul>
</nav>
</div>
);
}
I am trying to make a Navbar but the isn't re-directing to the given page. If I click any of the links in the Navbar, it would change the path in the url bar but won't re-direct to that page. I am not sure if I am missing anything. When I replace it with the tags, it works perfectly.
Navbar.js
import React from "react";
import { BrowserRouter as Router, Link, Switch } from "react-router-dom";
const Navbar = () => {
return (
<Router>
<Switch>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/articles">Articles</Link>
</li>
<li>
<Link to="/articles-all">All articles</Link>
</li>
</ul>
</nav>
</Switch>
</Router>
);
};
export default Navbar;
App.js
import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import './App.css'
//pages
import Home from "./Pages/Home";
import About from "./Pages/About";
import Articles from "./Pages/Articles";
import ArticlesList from "./Pages/ArticlesList";
//components
import Navbar from './components/Navbar';
const App = () => {
return (
<div>
<Navbar/>
<Navigation />
</div>
);
};
export default App;
const Navigation = () => {
return (
<Router>
<div id="page-body">
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/articles" component={Articles} />
<Route path="/articles-all" component={ArticlesList} />
</div>
</Router>
);
};
Since you define the Router within Navigation and another one in Navbar your Links are not able to communicate to the Router Component in Navigation as they just communicate to their nearest parent Router component
You must you use a single Router instance to be able to perform seemless navigation within your App. Also a Switch component is not needed with Links but with Route
const App = () => {
return (
<Router>
<Router component={Navbar}/> // rendered as default route so that they receive router props
<Router component={Navigation} />
</Router>
);
};
export default App;
const Navigation = () => {
return (
<div id="page-body">
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/articles" component={Articles} />
<Route path="/articles-all" component={ArticlesList} />
</div>
);
};
const Navbar = () => {
return (
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/articles">Articles</Link>
</li>
<li>
<Link to="/articles-all">All articles</Link>
</li>
</ul>
</nav>
);
};
export default Navbar;
Here's a working codesandbox URL https://codesandbox.io/s/frosty-black-3i8hp?file=/src/App.js
You were wrapping links with browserRouter and Switch. These APIs are intended to wrap Routes only.
So, It wasn't able to communicate well with your react app.
I'm trying to render a component inside my dashboard component by clicking a Link in that component,
I need to render Home or Contacts or About component inside my div
should I use array to store the components I want to render or route? adn how do I do it?
import React, { useContext, useEffect, useState, Fragment } from "react";
import { BrowserRouter as Router, Route, Switch, Link } from "react-router-dom";
import Home from "./Home";
import About from "./About";
import Contacts from "./Contacts";
const DashBoard = () => {
const authContext = useContext(AuthContext);
return (
<div>
<div> // this is my side nav
<Route>
<ul>
<li>
<Link to="/dashboard/home">Home</Link>
</li>
<li>
<Link to="/">Issues</Link>
</li>
<li>
<Link to="/">Contacts</Link>
</li>
<li>
<Link to="/dashBoard/about">About</Link>
</li>
</ul>
</Route>
</div>
<div>
<nav>
<button
className="btn btn-primary"
id="menu-toggle"
onClick={() => setIsToggled(!isToggled)}
>
Toggle Menu
</button>
</nav>
<div className="container-fluid">
// i need to render a component here ex.) <Home/> | <Contacts/> | <About/> when a Link is clicked!
</div>
</div>
</div>
);
};
export default DashBoard;
in my app.js
<Fragment>
<Navbar />
<div className="">
<Switch>
<Route exact path="/dashBoard" component={DashBoard} />
<Route exact path="/login" component={Login} />
</Switch>
</div>
</Fragment>
I'm working on React app and trying to deploy on IIS.
It works fine but the Router is not showing correctly.
My expected path when I click the link 'Test' is 'http://localhost/test/TestRouter/' but it displays 'http://localhost/TestRouter/' instead.
Here is my code:
App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Test from './Test';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
function App() {
return (
<div className="App">
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/TestRouter/">Test</Link>
</li>
</ul>
</nav>
<Route path="/TestRouter/" component={Test} />
</div>
</Router>
</div>
);
}
export default App;
Test.js
import React from 'react';
class Test extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<p>Test</p>
</div>
);
}
}
export default Test;
package.json:
"homepage": "/test/",
Then I deploy on IIS, under Default Web Site/test
My problem is when I click 'Test' link, the url now displays 'http://localhost/TestRouter/'.
My expectation is that the url should displays 'http://localhost/test/TestRouter/'.
Is there anyone here can help me to correct the Router?
Thank you in advanced.
You need to add basename to the Router:
<Router basename='/test'>
path="test/TestRouter"
There is option to fill the path directly
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/test/TestRouter">Test</Link>
</li>
</ul>
</nav>
<Route path="test/TestRouter" component={Test} />
</div>
</Router>
And option like the comment here
<Router basename='/test'>
<div>
<nav>
<ul>
<li>
<Link to="/TestRouter">Test</Link>
</li>
</ul>
</nav>
<Route path="/TestRouter" component={Test} />
</div>
</Router>
Did you sure you try this as it wrote?
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.