How do I correctly use IndexRoute in React Router? - javascript

I am using React for a small web-app. It has a basic 5 page website layout. (Home|About|Contact|Press|Shows) so I wanted to use an app template that just displays a menu, the header and the footer, and the {props.children} would be the React Router's route component. To achieve this, I used the following code. Assume all the imports are there...
Here is my router code:
export default (props) => {
return (
<Router history={ hashHistory }>
<Route path="/" component={ Template }>
<IndexRoute component={ Home }></IndexRoute>
<Route path="about" component={ About }></Route>
<Route path="music" component={ Music }></Route>
<Route path="store" component={ Store }></Route>
<Route path="shows" component={ Shows }></Route>
<Route path="contact" component={ Contact }></Route>
</Route>
</Router>
);
}
Now here is my template:
export default ( props ) => {
return (
<div className="container">
<Header />
<Menu />
{ props.children }
<Footer />
</div>
);
}
I know something is wrong, b/c without CSS magic, a:active is always HOME and any other active pages. I.E. if I click About, then both Home and About are active. How can I correctly use an index route, or should I even use an index route in this simple of an app? If not, then how else can I use a template like the one I have and pass in a page as a component in a different way?
Update: Here is my Menu.js file...
const Menu = () => {
return (
<div>
<nav>
<Link activeClassName="nav-active" to="/">Home</Link>
<Link activeClassName="nav-active" to="about">About</Link>
<Link activeClassName="nav-active" to="music">Music</Link>
<Link activeClassName="nav-active" to="shows">Shows</Link>
<Link activeClassName="nav-active" to="store">Store</Link>
<Link activeClassName="nav-active" to="contact">Contact</Link>
</nav>
<hr className="line" />
</div>
);
}
export default Menu;

for index route you should use IndexLink comp , otherwise 'Home' will be active allways
import {Link,IndexLink} from 'react-router';
<IndexLink activeClassName="nav-active" to="/">Home</IndexLink>
<Link activeClassName="nav-active" to="about">About</Link>
<Link activeClassName="nav-active" to="music">Music</Link>
...

Related

Why does my react-router Link not take me to the other page (React JS)?

I have this code inside my App.js and i declared those routes:
function App() {
return (
<BrowserRouter>
<div className='App'>
<Switch>
<Route exact path="/"><Index /></Route>
<Route exact path="/contact"><Contact /></Route>
</Switch>
</div>
</BrowserRouter>
);
}
export default App;
And then in my Navbar.js i declared this link to /contact:
<Link to={ "/contact" } className="nav-item nav-link">Contact</Link>
And it doesn't work, the url changes into "http://localhost:3000/contact" but it remains in the index page, and the weird thing is that when i type exactly the same url in the url box it takes me to the contact page
Syntax error.
You wrote : Link to={ "/contact" } but it will be like : <Link to="/contact">Contact</Link>
I think It will be solved.
Your code wrong it shold be like that: to="/contact"
Well I would alter the code slightly:
import { BrowserRouter, Route, Routes } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<div className='App'>
<Routes>
<Route index element={<Index />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</div>
</BrowserRouter>
);
}
export default App;
The link code you have I've altered slightly too:
<Link to="/contact" className="nav-item nav-link">Contact</Link>
That's how we have ours and it is working fine, should be for you too.

How can I render different news components into the Navbar Component & display their data on the Navbar page, On Click of Navbar menu links

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>
</>
)
}

Website only changes after reload - react router

I would like to make a navbar with different Links to different routes. In another file, I have the react-router stuff in order to change the website. But when I press on the links it works but only if I reload afterward.
The head file:
export default function Head(props){
return(
<Router>
<div className="Head">
<div className="HeadItemFirst">bwftp</div>
<div className="HeadPaths">
<Link className="HeadItem" to="/"><div>Start</div></Link>
<Link className="HeadItem" to="/about"><div>about</div></Link>
<Link className="HeadItem" to="/settings"><div>Settings</div></Link>
</div>
</div>
</Router>
)
}
And the App file:
export default function App(){
return(
<div className="App">
<Head />{/* Here are all the links in a navbar stored */}
<Body />
<Foot />
<Router>
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/about" exact component={About}/>
<Route path="/settings" exact component={Settings}/>
<Route render={()=>(<h1>404</h1>)}/>
</Switch>
</Router>
</div>
)
}
You need not use multiple router instances in your Application. Instead have one at the topmost parent level. If you use multiple Routes, the Link components inside Head will communicate with the Router component inside Head only and will not relay the information of route change to Router in App
Also if you render Head as a default Route it will receive all props from Route and will ensure smooth functioning of the Routes
export default function Head(props){
return(
<div className="Head">
<div className="HeadItemFirst">bwftp</div>
<div className="HeadPaths">
<Link className="HeadItem" to="/"><div>Start</div></Link>
<Link className="HeadItem" to="/about"><div>about</div></Link>
<Link className="HeadItem" to="/settings"><div>Settings</div></Link>
</div>
</div>
)
}
export default function App(){
return(
<Router>
<div className="App">
<Route component={Head} /> //Render as a default route so that it gets route params
<Body />
<Foot />
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/about" exact component={About}/>
<Route path="/settings" exact component={Settings}/>
<Route render={()=>(<h1>404</h1>)}/>
</Switch>
</div>
</Router>
)
}

react router dom library doesn't work for my project

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

React-router v4 updates url but doesn't render component

I'm using react-router v4, no redux. The code example is below:
class MainPage extends Component {
render() {
return (
<div className="MainPage">
<BrowserRouter>
<Switch>
{/* <Route exact path='/' /> */}
<Route path='/signin' component={SignIn}/>
<Route path='/signup' component={SignUp} />
<Redirect from='*' to='/' />
</Switch>
</BrowserRouter>
</div>
);
}
}
When I'm using Link it updates URL in browser but doesn't render anything, nothing happens. When I resfresh, everything becomes fine and component renderes;
export default class Navbar extends Component {
render() {
return (
<div className="navbar">
<BrowserRouter>
<div>
<Link to='/signin'>Sign in</Link>
<Link to='/signup'>Sign up</Link>
</div>
</BrowserRouter>
</div>
);
}
}
I already tried everything, even withRouter(Component), but it says that with router may only be used inside
How can I deal with this?
Here is the working code. As others explained you should use one BrowserRouter. If you want to render your Navbar component all the time then you should place it above Switch but under BrowserRouter hence you need Link there.
const Navbar = () => (
<div className="navbar">
<Link to='/signin'>Sign in</Link>
<Link to='/signup'>Sign up</Link>
</div>
);
class MainPage extends React.Component {
render() {
return (
<div className="MainPage">
<BrowserRouter>
<div>
<Navbar />
<Switch>
{/* <Route exact path='/' /> */}
<Route path='/signin' component={SignIn} />
<Route path='/signup' component={SignUp} />
<Redirect from='*' to='/' />
</Switch>
</div>
</BrowserRouter>
</div>
);
}
}
You should only have a single BrowserRouter component in your tree. The BrowserRouter component holds the shared state the router used to synchronize the URL with the rendered routes. In your situation, you are getting two different versions of router state because you rendering two BrowserRouter components so you should probably render a single BrowserRouter component somewhere higher in your component tree.
If you have an App component that renders both Navbar and MainPage then you can move the router into that component:
export default class App extends Component {
render() {
return (
<BrowserRouter>
<div className="AppContainer">
<Navbar />
<MainPage />
</div>
</BrowserRouter>
);
}
}

Categories

Resources