navitem 中的 React-Bootstrap 链接项

Posted

技术标签:

【中文标题】navitem 中的 React-Bootstrap 链接项【英文标题】:React-Bootstrap link item in a navitem 【发布时间】:2016-06-11 18:31:48 【问题描述】:

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

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>

这是渲染时的样子。

我知道是&lt;Link&gt;&lt;/Link&gt; 造成了这种情况,但我不知道为什么?我希望这是在线的。

【问题讨论】:

【参考方案1】:

你不应该将锚点放在NavItem 中。通过这样做,您将在控制台中看到警告:

Warning: validateDOMNesting(...): &lt;a&gt; cannot appear as a descendant of &lt;a&gt;. See Header &gt; NavItem &gt; SafeAnchor &gt; a &gt; ... &gt; Link &gt; a.

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

由于上面的警告,react 将被强制将两个锚视为兄弟,这导致了样式问题。

【讨论】:

我最终不得不使用linkcontainer。 你能举个例子吗? 我是唯一一个不是通过接受的答案而是通过第二个答案解决问题的人吗? @chadschmidt 请将接受的答案更改为***.com/a/36933127/1826429【参考方案2】:

使用来自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>

在谷歌搜索这个问题时,这主要是给未来自己的一个注释。我希望其他人可以从答案中受益。

【讨论】:

+1:official recommendation from react-bootstrap, and react-router,就是使用react-router-bootstrap。 切换 activeClassName 怎么样? 如果你不能完成这项工作,只需确保你的路径包含在 React Router 中。 这无法将“活动”样式应用于 NavItem。 我在下面添加了一个答案,解决了 active/activeKey 不起作用的问题。也适用于 react-bootstrap v_1.0 beta! (要使用普通版本,只需从 NavItem 中分出 Nav.Item,依此类推)【参考方案3】:

这是一个与 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)【参考方案4】:

你可以使用history,只要确保创建组件with 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>

【讨论】:

【参考方案5】:

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

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 并没有按照您的指示工作。如果我直接转到一条路线,它将突出显示正确的路线,但如果我只是单击链接,则不会。 顺便说一句,你是怎么找到IndexLinkContainer的?在文档中的任何地方都找不到它... @ThomasLe 检查您使用的 Component 与 PureComponent。我通过切换到组件修复了一些更新的问题【参考方案6】:

你试过使用 react-bootstrap 的 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>

【讨论】:

这很好用!没有样式问题,并且比其他需要覆盖的答案简单得多,您也可以使用 HoC 覆盖,以避免重复 href / to。 这很干净,我现在将它与“目标空白”一起用于外部链接,效果很好。谢谢 这样更好,不需要包含另一个包。 刚刚升级到 1.0.0-beta.5。似乎他们删除了对 componentClass 的支持 :(【参考方案7】:

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

【讨论】:

【参考方案8】:

2020 年更新: 使用 react-boostrap: 1.0.0-beta.16react-router-dom: 5.1.2 测试

2019 年更新: 对于使用 react-bootstrap v4(目前使用 1.0.0-beta.5)和 react-router-dom v4 (4.3.1) 的用户,只需使用 "as " 来自 Nav.Link 的道具,这里是完整的例子:

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'。 这适用于带有 react-bootstrap 1 的 react router v5 和 react 16.8 使用此解决方案而不是来自react-router-bootstrapLinkContainer,因为此解决方案支持activeClassName 经过数小时研究这个问题,这是最好的解决方案 这是正确的解决方案,应该标记为答案。【参考方案9】:

你可以避免使用 react-router-bootstrap 中的LinkContainer。但是,componentClass 将在下一个版本中变为 as。因此,您可以在最新版本(v1.0.0-beta)中使用以下 sn-p:

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

【讨论】:

【参考方案10】:

对于使用 Gatsby 的人。如果您使用的是 NavBar 和 NavDropdown,并且您想在 NavDropdown.Item 中使用 Link,您将收到以下错误:

<a> cannot be descendant of <a>

要修复此错误,请尝试使用 as="li" :

 <NavDropdown title="Services" id="basic-nav-dropdown">
    <NavDropdown.Item as="li">
      <Link to="/Services" className="nav-link">
        Services
      </Link>
    </NavDropdown.Item>
  </NavDropDown>

【讨论】:

以上是关于navitem 中的 React-Bootstrap 链接项的主要内容,如果未能解决你的问题,请参考以下文章

React Bootstrap,为 NavItems 添加悬停效果

JSX 中的标记属性 [重复]

在 JSX 中返回多个元素

ml-auto没有将导航栏链接推向右侧

WordPress/PHP 获取主导航中所有链接的列表

如何修复 CSS 导航闪烁问题