React Router v4 - Как установить активный родительский элемент (li) из компонента Link [duplicate]

попробуйте это .. вы просто добавляете нули в зависимости от величины.

cout << hex << "0x" << ((c<16)?"0":"") << (static_cast<unsigned int>(c) & 0xFF) << "h" << endl;

Вы можете легко изменить это, чтобы работать с большими числами.

cout << hex << "0x";
cout << ((c<16)?"0":"") << ((c<256)?"0":"");
cout << (static_cast<unsigned int>(c) & 0xFFF) << "h" << endl;

Коэффициент равен 16 ( для одной шестнадцатеричной цифры): 16, 256, 4096, 65536, 1048576, .. соответствующие 0x10, 0x100, 0x1000, 0x10000, 0x100000, ..

Поэтому вы также можете писать так:

cout << hex << "0x" << ((c<0x10)?"0":"") << ((c<0x100)?"0":"") << ((c<0x1000)?"0":"") << (static_cast<unsigned int>(c) & 0xFFFF) << "h" << endl;

И так далее ..: P

39
задан abekenza 28 January 2016 в 05:57
поделиться

10 ответов

Вы должны заключить свой <li> в качестве компонента, поддерживающего маршрутизатор:

import { Link, IndexLink } from 'react-router'

class NavItem extends React.Component {
  render () {
    const { router } = this.context
    const { index, onlyActiveOnIndex, to, children, ...props } = this.props

    const isActive = router.isActive(to, onlyActiveOnIndex)
    const LinkComponent = index ? Link : IndexLink

    return (
      <li className={isActive ? 'active' : ''}>
        <LinkComponent {...props}>{children}</LinkComponent>
      </li>
    )
  }
}

Использование:

<ul>
  <NavItem to='/' index={true}>Home</NavItem>
  <NavItem to='/a'>A</NavItem>
</ul>

Я принял участие в модуле response-router-bootstrap , https://github.com/react-bootstrap/react-router-bootstrap/blob/master/src/LinkContainer.js . Я не тестировал его, хотя дайте мне знать, как это происходит.

34
ответ дан Marc Greenstock 15 August 2018 в 14:25
поделиться
  • 1
    В зависимости от вашей установки вам может понадобиться NavLi.contextTypes = { router: React.PropTypes.object }; export default NavLi; – Ted 25 December 2016 в 02:18
  • 2
    Также как & lt; NavItem to = & quot; / & quot; onlyActiveOnIndex ... – Ted 25 December 2016 в 02:20
  • 3
    Возможно, вам потребуется убедиться, что ваш компонент получает контекст, например. router: PropTypes.object.isRequired – timbo 4 May 2017 в 23:43
  • 4
    Вместо того, чтобы получать router через контекст, используйте withRouter HOC из пакета react-router, чтобы получить маршрутизатор через реквизиты. Это также обновит активный статус ссылки при изменении страницы, так как в противном случае React не имеет способа узнать, изменилось ли isActive. – Travis 18 July 2017 в 14:53
  • 5
    – Bastian Voigt 17 September 2018 в 10:56
/**
 * A navigation component
 */
import React, { Component } from 'react'
import { Link, IndexLink, withRouter } from 'react-router'

import styles from './styles.scss'

class NavItem extends Component {
  render () {
    const { router } = this.props
    const { index, to, children, ...props } = this.props

    let isActive
    if( router.isActive('/',true) && index ) isActive = true
    else  isActive = router.isActive(to)
    const LinkComponent = index ?  IndexLink : Link

    return (
      <li className={isActive ? 'active' : ''}>
        <LinkComponent to={to} {...props}>{children}</LinkComponent>
      </li>
    )
  }
}

NavItem = withRouter(NavItem)

export default NavItem

Использование:

<ul className="nav nav-tabs"> 
  <NavItem to='/home' index={true} >Home</NavItem>
  <NavItem to='/about'>About</NavItem>
</ul>
10
ответ дан bryanyu 15 August 2018 в 14:25
поделиться
  • 1
    Хотя на первый взгляд он похож на ответ Марка, этот ответ работал лучше для меня. withRouter похоже, что в текущих версиях для доступа к маршрутизатору. – Nick 11 October 2016 в 12:36
  • 2
    Это сработало для меня, но поскольку я использовал IndexLink, я сделал это одно изменение: else isActive = router.isActive (to, true). Я должен был добавить true к функции IsActive, иначе isActive всегда возвращался true для '/'. – CLaff 21 December 2016 в 03:54
  • 3
    Не работал: router для меня не определено, не найдено в this.props :-( – Derek 16 December 2017 в 16:40

Используя реакцию 15.1.0, реактивный маршрутизатор 2.5.0 и бутстрап 3.3 (это менее важно), я разработал это решение для активирования ссылок:

npm install --save classnames

npm install --save lodash

Компонент:

import React from 'react';
import { Link, IndexLink } from 'react-router';
import _ from 'lodash';
import classnames from 'classnames';

class NavItem extends React.Component {
  constructor(props) {
    super(props);

    // The default state
    this.state = {
      isActive: false,
      unregisterRouteListener: false
    };

    // Binding for functions
    this.locationHasChanged = this.locationHasChanged.bind(this);
  }

  componentDidMount() {
    // Check if component is active on mount and add listener on route change
    this.setState({
      isActive: this.context.router.isActive(this.props.to, true),
      unregisterRouteListener: this.context.router.listen(this.locationHasChanged)
    });
  }

  componentWillUnmount() {
    if (this.state.unregisterRouteListener) {
      // Remove the listener
      this.state.unregisterRouteListener();
    }

    // Reset the state
    this.setState({
      isActive: false,
      unregisterRouteListener: false
    });
  }

  // Update the state of the component, based on the router path
  locationHasChanged() {
    this.setState({
      isActive: this.context.router.isActive(this.props.to, true)
    });
  }

  render () {
    let { index } = this.props;
    let LinkComponent = index ? Link : IndexLink;
    let newProps = _.omit(this.props, 'router');

    return (
      <li className={classnames('', this.state.isActive ? 'active' : '' )}>
        <LinkComponent {...newProps}>
          {this.props.children}
        </LinkComponent>
      </li>
    );
  }
}

NavItem.contextTypes = {
  router: React.PropTypes.object
};

export default NavItem;

Использование:

<NavItem to="/list">List</NavItem>

Я начинаю с React, поэтому решение, улучшения и могут содержать ошибки подхода. Однако он также может содержать полезную информацию или отправную точку для заинтересованных лиц.

Любая обратная связь или предложения более чем приветствуются. Благодаря! :)

1
ответ дан Cristi Draghici 15 August 2018 в 14:25
поделиться

Вместо использования <Link /> я использую <NavLink />, и он также работает.

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

//.....

export default class AppNav extends Component {

    render (){
        return (
                <header>
                    <ul className="main-nav">
                        <li><NavLink activeClassName={"active"} exact={true} to="/">Home</NavLink></li>
                        <li><NavLink activeClassName={"active"} to="/about">About</NavLink></li>
                        <li><NavLink activeClassName={"active"} to="/courses">Courses</NavLink></li>
                    </ul>
                </header>
        );
    }
}
6
ответ дан Dimang Chou 15 August 2018 в 14:25
поделиться
  • 1
    Это исправило мою проблему. Интересно, какая разница между ними делает работу? – Evildonald 31 August 2017 в 05:30
  • 2
    Работал для меня, не нужно никаких обходных решений. Должен отметить это как лучший ответ. – tmh 23 December 2017 в 22:48
  • 3
    Является ли это установкой класса родительского элемента <li>? Для меня он просто устанавливает класс <a>, созданный из <NavLink>. – Abhisek 2 May 2018 в 03:06
  • 4
    – Goran Jakovljevic 1 September 2018 в 10:55

Попробуйте использовать active-router-active-component .

Я не мог легко получить какие-либо из предыдущих ответов из-за несовместимости между версиями реакции или типов (это определенно не зрелая экосистема), но этот компонент сделал трюк и может быть применен к другим элементам, чем li при необходимости:

import activeComponent from 'react-router-active-component'
let NavItem = activeComponent('li');
...
<NavItem to='/' onlyActiveOnIndex>Home</NavItem>
<NavItem to='/generate-keywords'>Generate keywords</NavItem>
1
ответ дан Erwin Mayer 15 August 2018 в 14:25
поделиться

Отличный ответ.

Просто измените следующее, чтобы заставить его работать ...

LinkComponent = index ? IndexLink : Link //If its true you want an IndexLink 

//Also link needs to be...
<NavItem to="/" onlyActiveOnIndex index={true}>Home</NavItem>
3
ответ дан hounded 15 August 2018 в 14:25
поделиться

Я использую React Router v4.2, и я не смог получить ссылку на объект маршрутизатора из компонента-оболочки, потому что контекст недоступен.

Это не сработало:

const { router } = this.context

Мне нравится @ mpen's answer , но я использую вложенные маршруты, и я не хочу изменять файл, в котором у меня установлен компонент маршрутизации.

То, что я сделал, сравнивает location.pathname с:

const NavItem = withRouter((props) => {
const { to, children, location } = props;
return (
    <li className={location.pathname == to ? 'active' : null}>
        <Link to={to}>{children}</Link >
    </li>
)});
0
ответ дан Jernej Gorički 15 August 2018 в 14:25
поделиться
{/* Make sure that `location` is injected into this component */}
<ul className="nav navbar-nav">
  <li className={location.pathname === '/' && 'active'}>
    <Link to='/'>
      Home page
    </Link>
  </li>
  <li className={location.pathname.startsWith('/about') && 'active'}>
    <Link to='/about'>
      About us
    </Link>
  </li>
</ul>
4
ответ дан Ken Berkeley 15 August 2018 в 14:25
поделиться

Другие ответы, похоже, не работают в React Router v4. Вот как вы можете это сделать:

import React, {PropTypes} from 'react'
import {Route, Link} from 'react-router-dom'
import styles from './styles.less';

export default function NavItem({children, to, exact}) {
    return (
        <Route path={to} exact={exact} children={({match}) => (
            <li className={match ? styles.activeRoute : null}>
                <Link to={to}>{children}</Link>
            </li>
        )}/>
    )
}

NavItem.propTypes = {
    to: PropTypes.string.isRequired,
    exact: PropTypes.bool,
    children: PropTypes.node.isRequired,
};
15
ответ дан mpen 15 August 2018 в 14:25
поделиться
  • 1
    Спасибо тебе за это. Я бы добавил ...props к параметрам и использовал его в <Link to={to} {...props}>{children}</Link> для более гибкого. – Tran Dinh Khanh 8 April 2017 в 06:15
  • 2
    я бы не использовал тернарный оператор и вместо этого использовал этот <li className={match && styles.activeRoute}> более краткий. – Sagiv b.g 20 September 2017 в 07:13
  • 3
    @ Sag1v Мне больше не нравится использовать этот синтаксис. Я получил бит, когда он оценил значение 0, и у меня был случайный 0 в моем пользовательском интерфейсе. Можете создать еще худшие ошибки, если вы не будете осторожны. – mpen 20 September 2017 в 18:56
  • 4
    @mpen Я знаю, что вы имеете в виду, хотя в этом случае 0 произведет тот же эффект, не так ли? – Sagiv b.g 20 September 2017 в 19:14
  • 5

Используя React Router v4, я получил его только для работы, включив теги <li> в компонент NavLink. Решения, которые имеют теги <li>, обертывающие ссылки, привели к тому, что тег HOME <li> всегда имел класс active.

import React from 'react'
import { NavLink } from 'react-router-dom';

class Header extends React.Component {

  render() {
    return (
      <div>
        <header>

          <nav>
            <ul>
              <NavLink activeClassName={"active"} exact={true} to="/"><li>Home</li></NavLink>
              <NavLink activeClassName={"active"} to="/about"><li>About</li></NavLink>
              <NavLink activeClassName={"active"} to="/courses"><li>Courses</li></NavLink>
            </ul>
          </nav>

        </header>
      </div>
    )
  }
}

export default Header

Я скорректировал селектора CSS li и a соответственно.

0
ответ дан Steve Breese 15 August 2018 в 14:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: