Елемент посилання React-Bootstrap у навігаційному вікні


85

У мене виникають проблеми зі стилізацією за допомогою реакції-маршрутизатора та реакції-завантаження. нижче - фрагмент коду

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>це спричиняє, але не знаю чому? Я хотів би, щоб це було в рядку.

Відповіді:


5

Не слід класти якір всередину NavItem. Роблячи це, ви побачите попередження в консолі:

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

Це тому, що коли NavItemвідображається якір (прямий дочірній елемент NavItem) вже є.

Через попереднє попередження, реакція буде змушена поводитися з двома якорями як із братом, що спричинило проблему зі стилем.


4
Мені довелося в кінцевому підсумку використовувати linkcontainer .
chad schmidt

3
Не могли б ви навести приклад?
Paschalidis Christos

5
Я єдиний, чия проблема вирішується не прийнятою відповіддю, а другою відповіддю.
Ejaz Karim

1
@chadschmidt, будь ласка, змініть прийняту відповідь на stackoverflow.com/a/36933127/1826429
Голді

247

Використання 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?
Анюл Рівас

Якщо ви не можете зробити це, просто переконайтеся, що ваш шлях включений у React Router.
Анант Сімран Сінгх

8
При цьому не вдається застосувати "активний" стиль до NavItems.
Даніель Арант,

1
Я додав відповідь нижче, яка вирішує проблему з активним / активним ключем не працює. Працює і з бета-версією реакції-завантажувача v_1.0! (Для використання у звичайній версії, просто додайте Nav.Item до NavItem тощо)
Young Scooter

50

2020 оновлено: протестовано за допомогою react-boostrap: 1.0.0-beta.16таreact-router-dom: 5.1.2

2019 оновлення: для тих, хто працює з реактором boot-strap v4 (на даний момент використовується 1.0.0-beta.5) та response-router-dom v4 (4.3.1), просто використовуйте "як" підказку від 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}'.
lannyboy

1
Це працює на реакційному маршрутизаторі v5 з реакцією-bootstrap 1 і реагувати 16.8
proc

Я походжу з Vue.js, де boostrap vue просто реалізує і управляє параметром "до", і мені це набагато простіше. Дякую за підказку, це дуже допомогло!
egdavid

1
Використовуйте це рішення замість LinkContainerfrom, react-router-bootstrapоскільки це рішення підтримує activeClassName.
takasoft

Дякую @Alexey. Провів години, намагаючись налагодити роботу LinkContainer, а потім знайшов цю відповідь.
Девід Іслі

31

Ви пробували використовувати response-bootstrap's 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
Це настільки чисто, що я використав його зараз із "цільовим пустим" для зовнішнього посилання і працює дуже добре. Дякую
Сауло Гомес,

1
Це краще, без необхідності включати інший пакет.
sbk201

2
Щойно оновлено до 1.0.0-beta.5. Здається, вони скасували підтримку компонентаClass :(
Nate-Bit Int

12

Ви можете уникнути використання LinkContainerз response-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

Ось рішення для використання з реакційним маршрутизатором 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

2

Ви можете використовувати історію , просто обов’язково створіть компонент за допомогою маршрутизатора :

в 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

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, і він не працює, як ви вказали. Якщо я перейду безпосередньо до маршруту, він виділить правильний, але ні, якщо я просто клацну посилання.
Thomas Le

До речі, просто цікаво, як ти знайшов IndexLinkContainer? не міг знайти ніде в документах до ...
Тхім Нгуєн

@ThomasLe Перевірте, чи використовуєте Component vs PureComponent. У мене було декілька оновлених проблем, виправлених переходом на Component
FrozenKiwi

0

Щоб додати функціональність за допомогою "активного ключа" в бета-версії response-bootstrap v_1.0, використовуйте такий формат:

<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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.