Mục liên kết React-Bootstrap trong navitem


85

Tôi đang gặp một số vấn đề về kiểu dáng khi sử dụng react-router và react-bootstrap. dưới đây là một đoạn mã

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>

Đây là những gì nó trông như thế nào khi nó hiển thị.

nhập mô tả hình ảnh ở đây

Tôi biết đó <Link></Link>là nguyên nhân nhưng tôi không biết tại sao? Tôi muốn cho điều này được trong dòng.

Câu trả lời:


6

Bạn không nên đặt neo bên trong NavItem. Bằng cách này, bạn sẽ thấy cảnh báo trong bảng điều khiển:

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

Đó là bởi vì khi NavItemđược hiển thị, một mỏ neo (con trực tiếp của NavItem) đã ở đó.

Do cảnh báo ở trên, react sẽ buộc phải coi hai anchor là anh em ruột, điều này gây ra vấn đề về kiểu dáng.


4
Tôi đã phải kết thúc bằng một linkcontainer .
chad schmidt

3
Bạn có thể vui lòng cho một ví dụ?
Paschalidis Christos

5
Tôi có phải là người duy nhất mà vấn đề được giải quyết không phải bằng một câu trả lời được chấp nhận mà là câu trả lời thứ hai.
Ejaz Karim

1
@chadschmidt, vui lòng thay đổi câu trả lời được chấp nhận thành stackoverflow.com/a/36933127/1826429
Goldy

245

Sử dụng LinkContainer từ react -router-bootstrap là cách tốt nhất. Đoạn mã sau sẽ hoạt động.

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>

Đây chủ yếu là một lưu ý cho bản thân trong tương lai, khi googling vấn đề này. Tôi hy vọng ai đó khác có thể hưởng lợi từ câu trả lời.



4
làm thế nào về việc chuyển đổi ActiveClassName?
Anyul Rivas

Nếu bạn không thể thực hiện điều này, chỉ cần đảm bảo rằng đường dẫn của bạn được bao gồm trong React Router.
Anant Simran Singh

8
Điều này không thể áp dụng kiểu "hoạt động" cho NavItems.
Daniel Arant

1
Tôi đã thêm một câu trả lời bên dưới để giải quyết vấn đề với active / activeKey không hoạt động. Hoạt động với cả phiên bản beta react-bootstrap v_1.0! (Để sử dụng với phiên bản bình thường, chỉ cần bỏ Nav.Item từ NavItem, v.v.)
Young Scooter

49

Cập nhật năm 2020: được thử nghiệm với react-boostrap: 1.0.0-beta.16react-router-dom: 5.1.2

Cập nhật 2019: đối với những người đang làm việc với react-bootstrap v4 (hiện đang sử dụng phiên bản 1.0.0-beta.5) và react-router-dom v4 (4.3.1) chỉ cần sử dụng "as" từ Nav.Link, đây là đầy đủ thí dụ:

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>

Đây là ví dụ hoạt động: https://codesandbox.io/s/3qm35w97kq


vừa thử, nó không hoạt động với 'as = {NavLink}'.
lannyboy

1
Điều này hoạt động trên bộ định tuyến phản ứng v5 với react-bootstrap 1 và react 16.8
proc

Tôi đến từ Vue.js, nơi boostrap vue chỉ đơn giản triển khai và quản lý tham số "to" và tôi thấy nó dễ dàng hơn nhiều. Cảm ơn vì mẹo dù sao, nó đã giúp rất nhiều!
egdavid

1
Sử dụng giải pháp này thay vì LinkContainertừ react-router-bootstrapvì giải pháp này hỗ trợ activeClassName.
takasoft

Cảm ơn bạn @Alexey. Đã dành hàng giờ để cố gắng làm cho LinkContainer hoạt động và sau đó tìm thấy câu trả lời này.
David Easley

31

Bạn đã thử sử dụng react-bootstrap's componentClasschưa?

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
Điều này hoạt động tốt! Không có vấn đề về kiểu dáng và đơn giản hơn nhiều so với các câu trả lời khác yêu cầu ghi đè, bạn cũng có thể ghi đè bằng HoC chỉ để tránh sự lặp lại của href / to.
Tim Lind

1
Điều này rất rõ ràng, tôi đã sử dụng nó ngay bây giờ với "target blank" cho một liên kết bên ngoài và hoạt động rất tốt. Cảm ơn
Saulo Gomes

1
Điều này tốt hơn, mà không cần phải bao gồm một gói khác.
sbk201 30/08/2016

2
Vừa được nâng cấp lên 1.0.0-beta.5. Có vẻ như họ đã xóa hỗ trợ cho componentClass :(
Nate-Bit Int vào

12

Bạn có thể tránh sử dụng LinkContainertừ react-router-bootstrap. Tuy nhiên, componentClasssẽ trở thành astrong bản phát hành tiếp theo. Vì vậy, bạn có thể sử dụng đoạn mã sau cho phiên bản mới nhất (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

Đây là một giải pháp để sử dụng với 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
};

Thay vì sử dụng router.transitionTo(href)sử dụngrouter.history.push(href)
Devasatyam

2

Bạn có thể sử dụng lịch sử , chỉ cần đảm bảo tạo thành phần với bộ định tuyến :

trong App.js:

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

const NavigationWithRouter = withRouter(Navigation);

//in render()
    <NavigationWithRouter />

trong 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

IndexLinkContainer là một lựa chọn tốt hơn LinkContainer nếu bạn muốn NavItem bên trong làm nổi bật cái nào đang hoạt động dựa trên lựa chọn hiện tại. Không cần trình xử lý lựa chọn thủ công

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>

Tôi không sử dụng các tab nhưng muốn liên kết trong thanh điều hướng của tôi được đánh dấu là đang hoạt động. Tôi đã thử sử dụng IndexLinkContainer và nó không hoạt động như bạn đã chỉ ra. Nếu tôi đi thẳng đến một tuyến đường, nó sẽ đánh dấu đúng tuyến nhưng không phải nếu tôi chỉ nhấp vào các liên kết.
Thomas Le

btw chỉ tò mò làm thế nào bạn tìm thấy IndexLinkContainer? không thể tìm thấy nó ở bất cứ đâu trong tài liệu tho ...
Thiêm Nguyễn

@ThomasLe Kiểm tra việc sử dụng Component so với PureComponent của bạn. Tôi đã có một vài vấn đề cập nhật cố định bằng cách chuyển sang Component
FrozenKiwi

0

Để thêm chức năng với phần mềm hỗ trợ "activeKey" trong phiên bản beta react-bootstrap v_1.0, hãy sử dụng định dạng sau:

<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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.