Выделите текущую страницу в bootstrap с реакцией - PullRequest
0 голосов
/ 16 января 2020

Я видел несколько вопросов, связанных с этим, и я попробовал их все, но безрезультатно. Итак, публикуя еще один, казалось бы, дублированный вопрос.

Я пытаюсь выделить кнопку текущей страницы на панели навигации. Для простых примеров, когда я не направляю его на новую страницу, это работает. Но когда я направляю его на другую страницу (отдельный компонент реакции), он не работает.

Вот код, который у меня есть:

App.jsx :

class App extends Component {
  render() {
    return (
        <BrowserRouter>
            <div>
                <Route exact={true} path='/' component={HomeApp}/>
                <Route path='/form' component={SomeForm}/>
            </div>
        </BrowserRouter>
    );
  }
}

NavigationBar.jsx

class NavigationBar extends Component {

    componentDidMount() {
        toggleIcon();
    }

    render() {
        return (<div id="topheader">
        <nav className="navbar navbar-expand-lg navbar-light bg-light ">

            <a className="navbar-brand" href="#">Whatever</a>

            <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"
                    aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                <span className="navbar-toggler-icon"></span>
            </button>

            <div className="collapse navbar-collapse" id="navbarNav">
                <ul className="navbar-nav nav nav-pills ml-auto">
                    <li className="nav-item active">
                        <a className="nav-link" href="/">Home <span className="sr-only">(current)</span></a>
                    </li>
                    <li className="nav-item">
                        <a className="nav-link" href="/form">Submit Form</a>
                    </li>
                    <li className="nav-item">
                        <a className="nav-link" href="#">Sign Up</a>
                    </li>
                    <li className="nav-item">
                        <a className="nav-link " href="#">Login</a>
                    </li>
                </ul>
            </div>
        </nav>
            </div>
        )
    }
}

export default NavigationBar

навигация. js

import $ from 'jquery';

export function toggleIcon() {
    $( '#topheader .navbar-nav a' ).on( 'click', function () {
        $( '#topheader .navbar-nav' ).find( 'li.active' ).removeClass( 'active' );
        $( this ).parent( 'li' ).addClass( 'active' );
    });
}

Как видно, Подсветка работает, когда я нажимаю Sign Up или Login, так как они не направляются ни к какому другому компоненту.

Но когда я нажимаю на Submit Form, который направляется на компонент SomeForm, подсветка возвращается к кнопке Home.

Для получения более подробной информации я публикую содержимое компонентов HomeApp и SomeForm:

HomeApp.jsx

class HomeApp extends Component {
    render() {
        return (
            <div className="container">
                <NavigationBar/>
                <Jumbotron/>
            </div>
        )
    }
}

export default HomeApp

SomeForm.jsx

class SomeForm extends Component {
    render() {
        return (<>
                <div className="container">
                    <NavigationBar>
                    </NavigationBar>
                </div>
            </>
        )
    }
}

export default SomeForm

Ответы [ 2 ]

0 голосов
/ 16 января 2020

Поскольку вам нужно выделить родительский элемент ссылки (li), вы можете использовать withRouter (или useLocation hook для функциональных компонентов) с NavLink от реагирования роутер в NavigationBar:

import React, { Component } from 'react';
import { withRouter } from 'react-router';

class NavigationBar extends Component {

    constructor(props) {
        super(props);
        this.renderMenuLink = this.renderMenuLink.bind(this);
    }

    componentDidMount() {
        toggleIcon();
    }

    renderMenuLink({ path, label }) {
        const { location } = this.props;
        const isActive = location.pathname === path;
        return (
            <li key={path} className={`nav-item ${isActive ? 'active' : ''}`}>
                <NavLink className="nav-link" to={path}>
                     {label}{isActive ? <span className="sr-only">(current)</span> : ''}
                </NavLink>
            </li>
        );
    }

    render() {
        const menuLinks = [
            { path: '/', label: 'Home' },
            { path: '/form', label: 'Submit Form' },
            { path: '/register', label: 'Sign Up' },
            { path: '/login', label: 'Login' },
        ];
        return (<div id="topheader">
        <nav className="navbar navbar-expand-lg navbar-light bg-light ">

            <a className="navbar-brand" href="#">Whatever</a>

            <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"
                    aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                <span className="navbar-toggler-icon"></span>
            </button>

            <div className="collapse navbar-collapse" id="navbarNav">
                <ul className="navbar-nav nav nav-pills ml-auto">
                    {menuLinks.map((menuLink) => this.renderMenuLink(menuLink))}
                </ul>
            </div>
        </nav>
            </div>
        )
    }
}

export default withRouter(NavigationBar);

0 голосов
/ 16 января 2020

Пожалуйста, следуйте этой структуре:

import { BrowserRouter, Switch, Route } from "react-router-dom"
class App extends React.Component{
  render() {
    return (
      <BrowserRouter>
        <div className="App">
          <Navigation />
          <Switch>
            <Route exact path="/" component={Home} />
            <Route exact path="/about" component={About} />
            <Route exact path="/contact" component={MoreRoutes} />
          </Switch>
        </div>
      </BrowserRouter>
    )
  }
}

И вам нужно использовать NavLink как упомянуто @Mikail Bayram, что позволит вам использовать activeClassName Кроме того, exact реквизит требуется на каждом из ваших маршрутов, чтобы маршруты отображались только тогда, когда путь имеет точное совпадение. Обратите внимание, что вы можете вызывать класс active как хотите.

Ваша навигация должна выглядеть следующим образом:

import { NavLink } from "react-router-dom"
const Navigation = () => (
  <nav>
    <ul>
      <li>
        <NavLink exact activeClassName="active" to="/">
          Home
        </NavLink>
      </li>
      <li>
        <NavLink exact activeClassName="active" to="/about">
          About
        </NavLink>
      </li>
      <li>
        <NavLink exact activeClassName="active" to="/contact">
          Contact
        </NavLink>
      </li>
    </ul>
  </nav>
)

В качестве примечания: Вам следует Никогда комбинация jQuery с React

Вот живой пример на codeSandbox

...