Element odsyłacza React-Bootstrap w elemencie navitem


85

Mam pewne problemy ze stylizacją podczas korzystania z React-router i React-bootstrap. poniżej znajduje się fragment kodu

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>

Tak to wygląda podczas renderowania.

wprowadź opis obrazu tutaj

Wiem, że <Link></Link>to powoduje, ale nie wiem dlaczego? Chciałbym, żeby to było w linii.

Odpowiedzi:


5

Nie należy umieszczać kotwicy w środku NavItem. Robiąc to, zobaczysz ostrzeżenie w konsoli:

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

Dzieje się tak, ponieważ kiedy NavItemjest renderowana kotwica (bezpośrednie dziecko NavItem) już tam jest.

Z powodu powyższego ostrzeżenia, firma reagująca będzie zmuszona traktować dwoje kotwic jako rodzeństwo, co spowodowało problem ze stylem.


4
Musiałem skończyć używając kontenera linków .
— chad schmidt

3
Czy mógłbyś podać przykład?
— Paschalidis Christos

5
Czy jestem jedynym, którego problem zostanie rozwiązany nie przez zaakceptowaną odpowiedź, ale drugą odpowiedź.
— Ejaz Karim

1
@chadschmidt, zmień zaakceptowaną odpowiedź na stackoverflow.com/a/36933127/1826429
— Goldy

247

Najlepszym rozwiązaniem jest użycie LinkContainer z React -router-bootstrap . Poniższy kod powinien działać.

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>

Jest to głównie uwaga dla przyszłego ja, podczas wyszukiwania tego problemu w Google. Mam nadzieję, że odpowiedź przyniesie korzyści komuś innemu.



4
co powiesz na przełączanie activeClassName?
— Anyul Rivas

Jeśli nie możesz tego zrobić, po prostu upewnij się, że Twoja ścieżka jest zawarta w React Router.
— Anant Simran Singh

8
To nie pozwala zastosować stylu „aktywnego” do NavItems.
— Daniel Arant,

1
Poniżej dodałem odpowiedź, która rozwiązuje problem z niedziałającym kluczem active / activeKey. Działa również z odpowiedzią-bootstrap v_1.0 beta! (Aby używać z wersją normalną, po prostu wyłącz Nav.Item z NavItem i tak dalej, i tak dalej)
— Young Scooter

50

Aktualizacja 2020: przetestowana z react-boostrap: 1.0.0-beta.16ireact-router-dom: 5.1.2

Aktualizacja 2019: dla tych, którzy pracują z reakcją-bootstrap v4 (obecnie używają 1.0.0-beta.5) i react-router-dom v4 (4.3.1) po prostu użyj "as" z Nav.Link, tutaj jest pełna przykład:

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>

Oto działający przykład: https://codesandbox.io/s/3qm35w97kq


właśnie wypróbowałem, po prostu nie działa z 'as = {NavLink}'.
— lannyboy

1
Działa to na routerze reaguj v5 z odpowiedzią-bootstrap 1 i reaguj 16.8
— proc.

Pochodzę z Vue.js, gdzie boostrap vue po prostu implementuje i zarządza parametrem „to” i jest to dla mnie znacznie łatwiejsze. Mimo wszystko dzięki za wskazówkę, bardzo pomogła!
— egdavid

1
Użyj tego rozwiązania zamiast LinkContainerfrom, react-router-bootstrapponieważ to rozwiązanie obsługuje activeClassName.
— takasoft

Dziękuję @Alexey. Spędziłem godziny, próbując uruchomić LinkContainer, a potem znalazłem tę odpowiedź.
— David Easley,

31

Czy próbowałeś użyć React-bootstrap 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
To działa dobrze! Żadnych problemów ze stylem i znacznie prostsze niż inne odpowiedzi, które wymagają nadpisania, możesz również zastąpić je za pomocą HoC, aby uniknąć powtórzenia href / to.
— Tim Lind,

1
To jest tak przejrzyste, że użyłem go teraz z „miejscem docelowym” dla linku zewnętrznego i działa bardzo dobrze. Dzięki
— Saulo Gomes

1
Tak jest lepiej, bez konieczności dołączania innego pakietu.
— sbk201

2
Właśnie zaktualizowano do wersji 1.0.0-beta.5. Wygląda na to, że usunęli obsługę componentClass :(
— Nate-Bit Int

12

Możesz uniknąć korzystania LinkContainerz opcji React-router-bootstrap. Jednak componentClassma się stać asw następnym wydaniu. Możesz więc użyć następującego fragmentu kodu dla ostatniej wersji (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

Oto rozwiązanie do użycia z routerem 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
};

Zamiast używać router.transitionTo(href)używaćrouter.history.push(href)
— Devasatyam

2

Możesz skorzystać z historii , pamiętaj tylko, aby utworzyć komponent z routerem :

w App.js:

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

const NavigationWithRouter = withRouter(Navigation);

//in render()
    <NavigationWithRouter />

w 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 jest lepszą opcją niż LinkContainer, jeśli chcesz, aby wewnętrzny element NavItem podświetlał, który jest aktywny w oparciu o bieżący wybór. Nie jest wymagana ręczna procedura wyboru

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>

Nie używam kart, ale chciałbym, aby link na moim pasku nawigacyjnym był podświetlony jako aktywny. Próbowałem użyć IndexLinkContainer i nie działa tak, jak wskazałeś. Jeśli przejdę bezpośrednio do trasy, podświetli właściwą, ale nie, jeśli po prostu kliknę linki.
— Thomas Le

przy okazji tylko ciekawostki, jak znalazłeś IndexLinkContainer? nie mogłem go znaleźć nigdzie w dokumentach, chociaż ...
— Thiem Nguyen,

@ThomasLe Sprawdź, czy używasz Component vs PureComponent. Kilka zaktualizowanych problemów zostało naprawionych, przełączając się na komponent
— FrozenKiwi

0

Aby dodać funkcjonalność za pomocą właściwości „activeKey” w wersji beta reagowania na bootstrap v_1.0, użyj tego formatu:

<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>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.