React-Bootstrap link item in a navitem
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.
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.
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
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>
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>
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.