【问题标题】:React-Bootstrap link item in a navitemnavitem 中的 React-Bootstrap 链接项
【发布时间】: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; 造成了这种情况,但我不知道为什么?我希望这是在线的。

【问题讨论】:

    标签: react-router react-bootstrap


    【解决方案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 将被强制将两个锚视为兄弟,这导致了样式问题。

    【讨论】:

    【解决方案2】:

    使用来自react-router-bootstrapLinkContainer 是可行的方法。以下代码应该可以工作。

    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>
    

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

    【讨论】:

    • 切换 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>
          

          【讨论】:

            猜你喜欢
            • 2017-06-11
            • 2017-06-16
            • 2019-07-04
            • 2018-12-05
            • 2017-10-16
            • 1970-01-01
            • 1970-01-01
            • 2018-04-17
            • 2021-08-17
            相关资源
            最近更新 更多