Reputation: 1022
I'm having some styling issues using react-router and react-bootstrap. below is a snippet of the code
import { Route, RouteHandler, Link } from 'react-router';
import AuthService from '../services/AuthService'
import { Button, Nav, Navbar, NavDropdown, MenuItem, NavItem } from 'react-bootstrap';
<Nav pullRight>
<NavItem eventKey={1}>
<Link to="home">Home</Link>
</NavItem>
<NavItem eventKey={2}>
<Link to="book">Book Inv</Link>
</NavItem>
<NavDropdown eventKey={3} title="Authorization" id="basic-nav-dropdown">
<MenuItem eventKey="3.1">
<a href="" onClick={this.logout}>Logout</a>
</MenuItem>
</NavDropdown>
</Nav>
This is what it looks like when it renders.
I know that the <Link></Link>
is causing this but I don't know why? I would like for this to be in-line.
Upvotes: 95
Views: 92170
Reputation: 159
For the people using Gatsby. If you are using a NavBar and a NavDropdown and you want to use a Link inside a NavDropdown.Item you will get an error that:
<a> cannot be descendant of <a>
For fixing this error try using as="li" :
<NavDropdown title="Services" id="basic-nav-dropdown">
<NavDropdown.Item as="li">
<Link to="/Services" className="nav-link">
Services
</Link>
</NavDropdown.Item>
</NavDropDown>
Upvotes: 1
Reputation: 2164
2020 upd: tested with react-boostrap: 1.0.0-beta.16
and react-router-dom: 5.1.2
2019 upd: for those who are working with react-bootstrap v4 (using 1.0.0-beta.5 currently) and react-router-dom v4 (4.3.1) just use "as" prop from Nav.Link, here is full example:
import { Link, NavLink } from 'react-router-dom'
import { Navbar, Nav } from 'react-bootstrap'
<Navbar>
{/* "Link" in brand component since just redirect is needed */}
<Navbar.Brand as={Link} to='/'>Brand link</Navbar.Brand>
<Nav>
{/* "NavLink" here since "active" class styling is needed */}
<Nav.Link as={NavLink} to='/' exact>Home</Nav.Link>
<Nav.Link as={NavLink} to='/another'>Another</Nav.Link>
<Nav.Link as={NavLink} to='/onemore'>One More</Nav.Link>
</Nav>
</Navbar>
Here is working example: https://codesandbox.io/s/3qm35w97kq
Upvotes: 74
Reputation: 241
You can avoid using LinkContainer
from react-router-bootstrap. However, componentClass
is going to become as
in the next release. So, you can use the following snippet for the last version (v1.0.0-beta):
<Nav>
<Nav.Link as={Link} to="/home" >
Home
</Nav.Link>
<Nav.Link as={Link} to="/book" >
Book Inv
</Nav.Link>
<NavDropdown title="Authorization" id="basic-nav-dropdown">
<NavDropdown.Item onClick={props.logout}>
Logout
</NavDropdown.Item>
</NavDropdown>
</Nav>
Upvotes: 16
Reputation: 504
To add functionality with "activeKey" prop in react-bootstrap v_1.0 beta, use this format:
<Nav activeKey={//evenKey you want active}>
<Nav.Item>
<LinkContainer to={"/home"} >
<Nav.Link eventKey={//put key here}>
{x.title}
</Nav.Link>
</LinkContainer>
</Nav.Item>
//other tabs go here
</Nav>
Upvotes: 1
Reputation: 6469
Have you tried using react-bootstrap's componentClass
?
import { Link } from 'react-router';
// ...
<Nav pullRight>
<NavItem componentClass={Link} href="/" to="/">Home</NavItem>
<NavItem componentClass={Link} href="/book" to="/book">Book Inv</NavItem>
</Nav>
Upvotes: 34
Reputation: 11701
IndexLinkContainer is a better option than LinkContainer if you want the inside NavItem to highlight which one is active based on the current selection. No manual selection handler is needed
import { IndexLinkContainer } from 'react-router-bootstrap';
....
//Inside render
<Nav bsStyle="tabs" >
<IndexLinkContainer to={`${this.props.match.url}`}>
<NavItem >Tab 1</NavItem>
</IndexLinkContainer>
<IndexLinkContainer to={`${this.props.match.url}/tab-2`}>
<NavItem >Tab 2</NavItem>
</IndexLinkContainer>
<IndexLinkContainer to={`${this.props.match.url}/tab-3`}>
<NavItem >Tab 3</NavItem>
</IndexLinkContainer>
</Nav>
Upvotes: 3
Reputation: 1176
Here is a solution for use with react-router 4:
import * as React from 'react';
import { MenuItem as OriginalMenuItem, NavItem as OriginalNavItem } from 'react-bootstrap';
export const MenuItem = ({ href, ...props }, { router }) => (
<OriginalMenuItem onClick={e => {e.preventDefault();router.transitionTo(href)}} href={href} {...props}/>
);
MenuItem.contextTypes = {
router: React.PropTypes.any
};
export const NavItem = ({ href, ...props }, { router }) => (
<OriginalNavItem onClick={e => {e.preventDefault();router.transitionTo(href)}} href={href} {...props}/>
);
NavItem.contextTypes = {
router: React.PropTypes.any
};
Upvotes: 5
Reputation: 2210
You can use history, just be sure to create the component with router:
in App.js:
// other imports
import {withRouter} from 'react-router';
const NavigationWithRouter = withRouter(Navigation);
//in render()
<NavigationWithRouter />
in Navigation.js:
//same code as you used before, just make an onClick event for the NavItems instead of using Link
<Nav pullRight>
<NavItem eventKey={1} onClick={ e => this.props.history.push("/home") } >
Home
</NavItem>
<NavItem eventKey={2} onClick={ e => this.props.history.push("/book") } >
Book Inv
</NavItem>
</Nav>
Upvotes: 2
Reputation: 2669
Using LinkContainer from react-router-bootstrap is the way to go. The following code should work.
import { Route, RouteHandler, Link } from 'react-router';
import AuthService from '../services/AuthService'
import { Button, Nav, Navbar, NavDropdown, MenuItem, NavItem } from 'react-bootstrap';
import { LinkContainer } from 'react-router-bootstrap';
/// In the render() method
<Nav pullRight>
<LinkContainer to="/home">
<NavItem eventKey={1}>Home</NavItem>
</LinkContainer>
<LinkContainer to="/book">
<NavItem eventKey={2}>Book Inv</NavItem>
</LinkContainer>
<NavDropdown eventKey={3} title="Authorization" id="basic-nav-dropdown">
<LinkContainer to="/logout">
<MenuItem eventKey={3.1}>Logout</MenuItem>
</LinkContainer>
</NavDropdown>
</Nav>
This is mostly a note to future self, when googling this issue. I hope someone else might benefit from the answer.
Upvotes: 254
Reputation: 4300
You should not put anchor inside NavItem
. By doing this you will see warning in the console:
Warning: validateDOMNesting(...): <a> cannot appear as a descendant of <a>. See Header > NavItem > SafeAnchor > a > ... > Link > a.
That's because when NavItem
is rendered an anchor (direct child of the NavItem
) is already there.
Because of the warning above, react will be forced to treat the two anchor as sibling, which caused the style issue.
Upvotes: 7