React-Bootstrap link navitem 中的项目
React-Bootstrap link item in a navitem
我在使用 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>
造成的,但我不知道为什么?我希望这是在线的。
你不应该把锚放在里面 NavItem
。通过这样做,您将在控制台中看到警告:
Warning: validateDOMNesting(...): <a> cannot appear as a descendant of <a>. See Header > NavItem > SafeAnchor > a > ... > Link > a.
那是因为当呈现 NavItem
时,锚点(NavItem
的直接子节点)已经存在。
由于上面的警告,react 会强制将两个anchor 视为兄弟,从而导致样式问题。
使用 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>
这主要是给未来的自己在谷歌搜索这个问题时的一个注释。我希望其他人可以从答案中受益。
这是一个与 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
};
您可以使用 history, just be sure to create the component 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>
如果您希望内部 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>
您尝试过使用 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>
要在 react-bootstrap v_1.0 beta 中使用 "activeKey" prop 添加功能,请使用此格式:
<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>
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>
您可以避免使用来自 react-router-bootstrap 的 LinkContainer
。但是,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>
对于使用 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>
我在使用 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>
造成的,但我不知道为什么?我希望这是在线的。
你不应该把锚放在里面 NavItem
。通过这样做,您将在控制台中看到警告:
Warning: validateDOMNesting(...): <a> cannot appear as a descendant of <a>. See Header > NavItem > SafeAnchor > a > ... > Link > a.
那是因为当呈现 NavItem
时,锚点(NavItem
的直接子节点)已经存在。
由于上面的警告,react 会强制将两个anchor 视为兄弟,从而导致样式问题。
使用 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>
这主要是给未来的自己在谷歌搜索这个问题时的一个注释。我希望其他人可以从答案中受益。
这是一个与 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
};
您可以使用 history, just be sure to create the component 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>
如果您希望内部 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>
您尝试过使用 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>
要在 react-bootstrap v_1.0 beta 中使用 "activeKey" prop 添加功能,请使用此格式:
<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>
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>
您可以避免使用来自 react-router-bootstrap 的 LinkContainer
。但是,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>
对于使用 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>