my name Rajdeep Singh. I'm using react-router-dom in my react project. when clicking on the Link tag, Link tag not work.im don't understand why not working.
in-browser change URL but a component, not change on the web app
check my code
This my Main.js Component file code
import React, { Fragment } from 'react';
import Foot from './Footer';
import Head from './Header'
import MainContect from './MainContect';
import About from './page/About';
import Book from './page/Book'
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
function Main() {
return (
// use Fragment
<Fragment>
{/* use BrowserRouter as Router */}
<Router>
{/* out Router use Head componet */}
<Head />
{/* use Switch tag */}
<Switch>
{/* use Route defined Router path */}
<Route path="/" exact >
{/* compnent name */}
<MainContect />
</Route>
<Route path="/book" >
<Book />
</Route>
<Route path="/about" >
<About />
</Route>
</Switch>
{/* out Router use Head componet */}
<Foot />
</Router>
</Fragment>
)
}
export default Main
This my Header.js component file code
import React from 'react';
import './css/header.scss';
import { BrowserRouter as Router, Link } from 'react-router-dom';
function Head() {
return (
// Use Router tag wrap all Link in Router
<Router>
<header>
<h1 className='logo'> Sikh Book</h1>
<div className="iconArea">+</div>
<ul className="ulArea">
<li>
{/* Use Link tag for navigation */}
<Link to="/"> Home </Link> </li>
<li>
<Link to="/book">
Book
</Link>
</li>
<li>
<Link to="/about">
About
</Link>
</li>
</ul>
</header>
</Router>
)
}
export default Head
Plz tell whats my mistake
thank for helping me
You should initiate the BrowserRouter only once. I'd do this at a high level of your component tree. You could look at this example.
// BrowserRouter is the router implementation for HTML5 browsers (vs Native).
// Link is your replacement for anchor tags.
// Route is the conditionally shown component based on matching a path to a URL.
// Switch returns only the first matching route rather than all matching routes.
import {
BrowserRouter as Router,
Link,
Route,
Switch,
} from 'react-router-dom';
import React from 'react';
const Home = () => <h1>Home</h1>;
const About = () => <h1>About</h1>;
// We give each route either a target `component`, or we can send functions in `render` or `children`
// that return valid nodes. `children` always returns the given node whether there is a match or not.
const App = () => (
<Router>
<div>
<Link to="/">Home</Link>{' '}
<Link to={{pathname: '/about'}}>About</Link>{' '}
<Link to="/contact">Contact</Link>
<Switch>
<Route path="/" component={Home} />
<Route path="/about" component={About} />
<Route
path="/contact"
render={() => <h1>Contact Us</h1>} />
<Route path="/blog" children={({match}) => (
<li className={match ? 'active' : ''}>
<Link to="/blog">Blog</Link>
</li>)} />
<Route render={() => <h1>Page not found</h1>} />
</Switch>
</div>
</Router>
);
Credits to: siakaramalegos
Related
I'm trying to create my first website, but having issues with redirection to another page. I added Routes to App.jsx, and added links to Navbar; clicking on "Services" in Navbar goes to "/services", but the page doesn't show anything, only Navbar.
I also tried with NavLink, but it did't change anything. Please help me figure out what the problem is.
import React from 'react';
import "./App.css";
import { BrowserRouter, Routes,Route } from "react-router-dom";
import Home from './pages/home/Home';
import Samples from './pages/samples/Samples';
import Services from './pages/services/Services';
import Navbar from './components/navbar/Navbar';
import Reviews from './components/reviews/Reviews';
import Contacts from './components/contacts/Contacts';
const App = () => {
return (
<div>
<BrowserRouter>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/services" element={<Services />} />
<Route path="/samples" element={<Samples />} />
{/* <Route path="#reviews" element={<Reviews />} /> */}
</Routes>
</BrowserRouter>
</div>
)
}
export default App
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import { RiMenuFill, RiCloseLine } from 'react-icons/ri';
import './navbar.css';
import MainLogo from "../../assets/MainLogo.png";
const Navbar = () => {
const [toggleMenu, setToggleMenu] = useState(false);
return (
<div>
<div className='navbar'>
<Link style={{textDecoration:"none"}} to="/">
<img src={MainLogo} alt="main_logo" className="navbar_logo"/>
</Link>
<ul className='navbar_links'>
<li>
<Link to="/services">Services</Link>
</li>
<li>
<Link to="/samples">Samples</Link>
</li>
<li>
<Link to="/">Reviews</Link>
</li>
<li>
<Link to="#gallery">Gallery</Link>
</li>
<li>
<Link to="#about">About Us</Link>
</li>
<li>
<Link to="#contacts">Contacts</Link>
</li>
</ul>
</div>
There is no issue with the routing. The issue here is that the navbar uses fixed positioning and the "/services" route content is rendered under the navbar.
Give the App component some top margin to push the content down below the navbar.
Example:
const App = () => {
return (
<div className='app'> // <-- app container
<BrowserRouter>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/services" element={<Services />} />
<Route path="/samples" element={<Samples />} />
{/* <Route path="#reviews" element={<Reviews />} /> */}
</Routes>
{/* <Reviews /> */}
</BrowserRouter>
</div>
)
}
app.css
.app {
margin-top: 93px; // <-- header/navbar height
}
I added {BrowserRouter} to index.js, and it worked
import React from "react";
import ReactDOM from "react-dom";
import App from './App';
import './index.css';
import { BrowserRouter } from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
)
I have made landing page where onClick of button it redirects to the Menus page/component where I have declared Navbar component & here only I want to render the different news category component on click of multiple nav menus of Navbar.
By using react-router-dom V6 how can I render different categories of news component underneath of Navbar.
Below is the code which I have tried yet.
App.js
import React from 'react';
import {Routes,Route} from 'react-router-dom';
import LandingPage from './Components/LandingPage';
import Menus from './Component/Menus;
const App = () => {
return (
<>
<Routes>
<Route path='/' element={<LandingPage/>} />
<Route path='menus' element={<Menus/>} />
</Routes>
</>
)
};
export default App;
Menus.js
import Navbar from './Navbar';
const Menus = () => {
return (
<div>
<Navbar/>
</div>
);
};
export default Menus;
Navbar.js
import '../Styles/Navbar.css';
import Entertainment from './Entertainment';
import Business from './Business';
import Health from './Health';
import Science from './Science';
import Sports from './Sports';
import Technology from './Technology';
import {Link,Route,Routes} from 'react-router-dom';
import {useState} from 'react';
const Navbar = ()=>{
const [isMobile,setIsMobile] = useState(false);
return(
<>
<nav className="navbar">
<h3 className="logo">theNews</h3>
<ul className={isMobile?'nav-links-mobile':'nav-links'}
onClick={()=>setIsMobile(false)}>
<Link to='/business' className='business'><li>Business</li></Link>
<Link to='/fun' className='fun'><li>Entertainment</li></Link>
<Link to='/health' className='health'><li>Health</li></Link>
<Link to='/science' className='science'><li>Science</li></Link>
<Link to='/sports' className='sports'><li>Sports</li></Link>
<Link to='/tech' className='tech'><li>Technology</li></Link>
</ul>
<button className='mobile-menu-icon' onClick={()=>setIsMobile(!isMobile)}>
{isMobile? <i className='fas fa-times'></i>:<i className='fas fa-bars' ></i>}
</button>
</nav>
<div>
<Routes>
<Route path='business' element={<Business/>}/>
<Route path='health' element={<Health/>} />
<Route path='science' element={<Science/>} />
<Route path='sports' element={<Sports/>} />
<Route path='tech' element={<Technology/>} />
<Route path='fun' element={<Entertainment/>} />
</Routes>
</div>
</>
)
}
export default Navbar;
If I understand your question correctly you are wanting to render Menus on the "/menus" path, and then also render sub-routes in Navbar being rendered by Menus. In react-router-dom v6 route paths are now always exactly matched, and the "/menus" root path precludes matching and rendering sub-routes.
The solution is to append a "*" wildcard matcher to the root path to allow additional route matching.
<Routes>
<Route path="/" element={<LandingPage/>} />
<Route path="/menus/*" element={<Menus/>} />
</Routes>
Additionally, in Navbar you are rendering relative route paths but specifying absolute route links. These should be in agreement. Remove the leading "/" character from the links so they are also relative to the "/menus" route path.
const Navbar = () => {
const [isMobile, setIsMobile] = useState(false);
return(
<>
<nav className="navbar">
<h3 className="logo">theNews</h3>
<ul className={isMobile?'nav-links-mobile':'nav-links'}
onClick={()=>setIsMobile(false)}>
<Link to='business' className='business'><li>Business</li></Link>
<Link to='fun' className='fun'><li>Entertainment</li></Link>
<Link to='health' className='health'><li>Health</li></Link>
<Link to='science' className='science'><li>Science</li></Link>
<Link to='sports' className='sports'><li>Sports</li></Link>
<Link to='tech' className='tech'><li>Technology</li></Link>
</ul>
<button className='mobile-menu-icon' onClick={()=>setIsMobile(!isMobile)}>
{isMobile? <i className='fas fa-times'></i>:<i className='fas fa-bars' ></i>}
</button>
</nav>
<div>
<Routes>
<Route path='business' element={<Business/>}/>
<Route path='health' element={<Health/>} />
<Route path='science' element={<Science/>} />
<Route path='sports' element={<Sports/>} />
<Route path='tech' element={<Technology/>} />
<Route path='fun' element={<Entertainment/>} />
</Routes>
</div>
</>
)
}
My App.js
import React from "react";
import { BrowserRouter, Route } from "react-router-dom";
import Home from "./Components/screens/Home";
import Signup from "./Components/screens/Signup";
import Signin from "./Components/screens/Login";
import Profile from "./Components/screens/Profile";
import CreatePost from "./Components/screens/createPost";
import Navbar from "./Components/Navbar";
function App() {
return (
<BrowserRouter>
<Navbar />
<Route path="/">
<Home />
</Route>
<Route path="/Signin">
<Signin />
</Route>
<Route path="/Signup">
<Signup />
</Route>
<Route path="/Profile">
<Profile />
</Route>
<Route path="/create">
<CreatePost />
</Route>
</BrowserRouter>
);
}
export default App;
my navbar is containing links of all pages and is using react-router-dom but my home page is always rendering above every page , it is containing 4 other page links including home, i have just shown home and signup as error is same with other pages as well
My Navbar.js
import React from "react";
import PeopleIcon from "#material-ui/icons/People";
import IconButton from "#material-ui/core/IconButton";
import { Link } from "react-router-dom";
import "../ComponentsCss/Navbar.css";
function Navbar() {
return (
<div>
<nav>
<div className="nav-wrapper white">
<Link to="/" className="brand-logo">
Instagram
</Link>
<ul id="nav-mobile" className="right hide-on-med-and-down">
<li>
<Link to="/Signin">Signin</Link>
</li>
<li>
<Link to="/Signup">Signup</Link>
</li>
<li>
<Link to="/Profile">Profile</Link>
</li>
<li>
<Link to="/create">create</Link>
</li>
</ul>
</div>
</nav>
</div>
);
}
export default Navbar;
Home.js
import React from "react";
import "../../ComponentsCss/Home.css";
function Home() {
return (
<div className="home">
<div className="card home-card">
<h5>Ramesh</h5>
<div className="card-image">
<img src="https://images.unsplash.com/photo-1542103749-8ef59b94f47e?ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8cGVyc29ufGVufDB8fDB8fA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60" />
</div>
<div className="card-content">
<i className="material-icons" style={{ color: "red" }}>
favorite
</i>
<h6>TItle</h6>
<p>this is amazing post</p>
<input type="text" placeholder="add a comment" />
</div>
</div>
</div>
);
}
export default Home;
Signup.js
import React from "react";
import { Link } from "react-router-dom";
import "../../ComponentsCss/Login.css";
function Signup() {
return (
<div className="my-card">
<div className="card auth-card input-field">
<h2>Instagram</h2>
<input type="text" placeholder="name" />
<input type="email" placeholder="email" />
<input type="password" placeholder="password" />
<button
className="btn waves-effect waves-light "
type="submit"
name="action"
>
Signup
</button>
<h5>
<Link to="/signin">Already have account?</Link>
</h5>
</div>
</div>
);
}
export default Signup;
complete github code -: https://github.com/dhruv354/instagram-frontend.git
You need to make your Home route only match when is that exact route, change your App with this:
import React from "react";
import { BrowserRouter, Route } from "react-router-dom";
import Home from "./Components/screens/Home";
import Signup from "./Components/screens/Signup";
import Signin from "./Components/screens/Login";
import Profile from "./Components/screens/Profile";
import CreatePost from "./Components/screens/createPost";
import Navbar from "./Components/Navbar";
function App() {
return (
<BrowserRouter>
<Navbar />
<Route exact path="/">
<Home />
</Route>
<Route path="/Signin">
<Signin />
</Route>
<Route path="/Signup">
<Signup />
</Route>
<Route path="/Profile">
<Profile />
</Route>
<Route path="/create">
<CreatePost />
</Route>
</BrowserRouter>
);
}
export default App;
Issue
By default, Routers inclusively match routes. In other words, all routes with a matching path will be matched and rendered. Think of the path prop as a path prefix, path="/" is a prefix for every path, so it will always be matched and rendered.
Solution
Use the Switch component to exclusively render only a single matching Route component, and order the routes so the more specific paths ("/profile") can be matched before less specific paths ("/"). Your home path "/" will typically be the last route since it is the least specific.
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
function App() {
return (
<Router>
<Navbar />
<Switch>
<Route path="/Signin">
<Signin />
</Route>
<Route path="/Signup">
<Signup />
</Route>
<Route path="/Profile">
<Profile />
</Route>
<Route path="/create">
<CreatePost />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Router>
);
}
Path order and specificity matter
In the Switch, path order and specificity matter.
If for a url "/foo/bar" and example paths:
"/foo"
"/foo/:id"
"/foo/bar"
"/foo" is a prefix for the other routes and less specific, but because of the order it will be matched and rendered since the url will match. If "/foo" wasn't there, then similarly "/foo/:id" would match and render when instead you really wanted that last "/foo/bar" path to be matched.
Update the order:
"/foo/bar"
"/foo/:id"
"/foo"
"bar" is more specific than placeholder ":id", and both are more specific than "/foo".
I'm trying to properly render my different components with the HTML/CSS sidebar with React Routes and Apollo.
I have a sidebar that correctly renders to the left of the screen and a little navbar on top of it, the space for the component is not being blocked by any css property.
The expected output is:
The actual output:
I've tried to place all the Routes inside the sidebar but every time I click on them, they don't load at all, the URL changes but the content doesn't and I need to reload the webpage for it take some effect. The help would be very much appreciated.
App.js
import React from 'react';
import ApolloClient from 'apollo-boost';
import {ApolloProvider} from '#apollo/react-hooks';
import { render } from 'react-dom';
import {BrowserRouter as Router, Route, Link,Switch} from 'react-router-dom';
import 'bootswatch/dist/flatly/bootstrap.min.css';
import Nav from './components/Nav'
import Home from './components/pages/Home'
import About from './components/pages/About'
import Articles from './components/article/Articles'
import Article from './components/article/Article'
const client = new ApolloClient({
uri: 'url in here'
});
const App = () => {
return (
<ApolloProvider client={client}>
<Router>
<div className="App">
<Nav/>
<Route exact path='/' component={Home} />
<Route exact path='/Articles' component={Articles} />
<Route exact path='/Articles/:id' component={Article} />
<Route exact path='/About' component={About} />
</div>
</Router>
</ApolloProvider>
);
}
render(<App />, document.getElementById('root'));
export default App;
Nav.js component
import React from 'react';
import {BrowserRouter as Link} from 'react-router-dom';
export default function Nav() {
return (
<div className="wrapper">
<nav id="sidebar">
<Link className="nav-link" to="/">
<h3>Home</h3>
</Link>
.
.
.
</nav>
<div id="content">
<nav className="navBar" >
</nav>
<div className ="ComponentRender">
Here's where the component should be rendered
</div>
</div>
</div>
)
}
I don't know about Apollo but I think you should move your routes from the App component to the Nav component, so the code would be:
App component:
const App = () => {
return (
<ApolloProvider client={client}>
<Router>
<div className="App">
<Nav/>
</div>
</Router>
</ApolloProvider>
);
}
And the Nav component:
export default function Nav() {
return (
<div className="wrapper">
<nav id="sidebar">
<Link className="nav-link" to="/">
<h3>Home</h3>
</Link>
.
.
.
</nav>
<div id="content">
<nav className="navBar" >
</nav>
<div className ="ComponentRender">
<Route exact path='/' component={Home} />
<Route exact path='/Articles' component={Articles} />
<Route exact path='/Articles/:id' component={Article} />
<Route exact path='/About' component={About} />
</div>
</div>
</div>
)
}
Don't forget to move imports from App to Nav as well.
I have these routes set up in app.js:
import { BrowserRouter, Route, Switch } from 'react-router-dom';
<BrowserRouter>
<Switch>
<Route name="overview" exact path="/" component={OverviewPage} />
<Route name="details1" exact path="/orders/:orderReference/details1" component={DetailsOnePage}/>
<Route name="details2" exact path="/orders/:orderReference/details2" component={DetailsTwoPage}/>
</Switch>
</BrowserRouter>
These routes are called via buttons in a smart component:
import { Link } from 'react-router-dom';
<IconButton aria-label="Details One">
<Link to="details1" params={{ orderReference: order.orderReference }}>
<PickingIcon />
</Link>
</IconButton>
I would expect this to route to:
http://localhost:3000/orders/my-reference/details1
But it goes to:
http://localhost:3000/details1
Which doesn't exist.
I checked, order.orderReference does indeed contain the value my-reference.
What's wrong with the above code?
In your Link to prop you have to provide the complete order path like
<Link to={`/orders/${order.orderReference}/details1`} >
<PickingIcon />
</Link>