导航栏中的React-Bootstrap链接项


85

我在使用react-router和react-bootstrap时遇到一些样式问题。下面是代码片段

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>

这就是渲染时的样子。

在此处输入图片说明

我知道<Link></Link>是造成这种情况的原因,但我不知道为什么?我希望这一点可以实现。

Answers:


6

你不应该在里面放锚NavItem。这样,您将在控制台中看到警告:

Warning: validateDOMNesting(...): <a> cannot appear as a descendant of <a>. See Header > NavItem > SafeAnchor > a > ... > Link > a.

这是因为NavItem渲染时已存在锚(的直接子代NavItem)。

由于上述警告,将不得不将react强制视为两个锚视为同级,从而导致样式问题。


4
我不得不结束使用linkcontainer
乍得·施密特

3
你能举个例子吗?
Paschalidis Christos

5
我是不是唯一一个解决问题的人,不是第二个答案。
Ejaz Karim

1
@chadschmidt请改变公认的答案stackoverflow.com/a/36933127/1826429
戈尔迪

245

react-router-bootstrap使用LinkContainer是可行的方法。下面的代码应该工作。

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>

搜寻此问题时,这主要是对未来自我的说明。我希望其他人可以从答案中受益。



4
如何切换activeClassName?
Anyul Rivas

如果您无法完成这项工作,只需确保您的路径包含在React Router中即可。
Anant Simran Singh

8
这无法将“活动”样式应用于NavItems。
Daniel Arant

1
我在下面添加了一个答案,该答案解决了active / activeKey无法正常工作的问题。也可以与react-bootstrap v_1.0 beta一起使用!(要与普通版本一起使用,只需将Nav.Item从NavItem中减去,依此类推)
Young Scooter

49

2020年更新:通过react-boostrap: 1.0.0-beta.16和测试react-router-dom: 5.1.2

2019年更新:对于正在使用react-bootstrap v4(当前使用1.0.0-beta.5)和react-router-dom v4(4.3.1)的用户,只需使用Nav.Link中的“ as”道具,即可使用例:

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>

这是工作示例:https : //codesandbox.io/s/3qm35w97kq


刚刚试用过,它与'as = {NavLink}'不兼容。
lannyboy

1
这适用于带有react-bootstrap 1和react 16.8的react路由器v5-
proc

我来自Vue.js,那里的boostrap vue只是实现并管理“ to”参数,我发现它要容易得多。无论如何,感谢您的提示,对您有很大帮助!
egdavid

1
使用此解决方案而不是LinkContainerfrom,react-router-bootstrap因为此解决方案支持activeClassName
takasoft

谢谢@Alexey。花了几个小时尝试使LinkContainer运行,然后找到了这个答案。
大卫·伊斯利

31

您是否尝试过使用react-bootstrap的componentClass

import { Link } from 'react-router';
// ...
<Nav pullRight>
  <NavItem componentClass={Link} href="https://stackoverflow.com/" to="/">Home</NavItem>
  <NavItem componentClass={Link} href="https://stackoverflow.com/book" to="/book">Book Inv</NavItem>
</Nav>

1
这很好!没有样式问题,并且比其他需要覆盖的答案要简单得多,您也可以使用HoC覆盖,以避免重复href / to。
蒂姆·林德

1
这非常干净,我现在将其与“目标空白”一起用于外部链接,并且效果很好。谢谢
索洛戈麦斯'18

1
这样更好,而无需包含另一个软件包。
sbk201 '18

2
刚刚升级到1.0.0-beta.5。看来他们删除了对componentClass的支持:(
Nate-Bit Int

12

您可以避免使用LinkContainerreact-router-bootstrap。但是,componentClass它将as在下一个版本中成为。因此,您可以将以下代码段用于最新版本(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>

5

这是与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
};

代替router.transitionTo(href)使用router.history.push(href)
Devasatyam '17

2

您可以使用 历史记录,只需确保使用router创建组件:

在App.js中:

// other imports
import {withRouter} from 'react-router';

const NavigationWithRouter = withRouter(Navigation);

//in render()
    <NavigationWithRouter />

在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>

2

如果您希望内部NavItem根据当前选择突出显示哪个处于活动状态,则IndexLinkContainer比LinkContainer更好。无需手动选择处理程序

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>

我没有使用标签页,但希望导航栏中的链接突出显示为活动状态。我尝试使用IndexLinkContainer,但它不能如您所指示的那样工作。如果我直接进入某条路线,它将突出显示正确的路线,但如果我仅单击链接则不会。
Thomas Le

顺便说一句,古玩是怎么找到的IndexLinkContainer?在文档中的任何地方都找不到它
Thiem Nguyen

@ThomasLe检查您使用的组件与PureComponent。我已经通过切换到组件解决了一些更新的问题
FrozenKiwi,

0

要在react-bootstrap v_1.0 beta中使用“ activeKey”道具添加功能,请使用以下格式:

<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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.