SO react-router-bootstrap 活动链接无法正常工作

Posted

技术标签:

【中文标题】SO react-router-bootstrap 活动链接无法正常工作【英文标题】:SO react-router-bootstrap active link not working properly 【发布时间】:2018-11-27 16:36:24 【问题描述】:

我在使用 react-router-bootstrap (https://www.npmjs.com/package/react-router-bootstrap) 组件的活动链接方面遇到问题。当我导航到 About 时,active 类不仅出现在 About 上,而且还出现在 Home 中。

Active Link react-router's issue

这是来自 react-bootstrap (https://react-bootstrap.github.io/) 的我的 Nav 组件:

NavLinks.jsx

import React,  Component  from 'react';
import  Nav, NavItem  from 'react-bootstrap';

import HashNavItem from '../../Navigation/HashNavItem';

// import Flags from './Flags/Flags'
import "./NavLinks.css";

const routes = [
  name: 'Home',
  path: '/',
  external: false
,
  name: 'About',
  path: '/about',
  external: false
, 
  name: 'Stores',
  path: '/#stores',
  external: false
, 
  name: 'My Account',
  path: 'http://my-react.appicar.com/',
  external: true
, 
  name: 'Services',
  path: '/#services',
  external: false
, 
  name: 'Reviews',
  path: '/#reviews',
  external: false
, 
  name: 'Contact',
  path: '/#contact',
  external: false
];

export default class MainNav extends Component 

  handleClick(e) 
    e.preventDefault();
    alert('hola');
  
  render() 
    let template;

    return (
      <Nav>
        
          routes.map((route, key) => 
            if (route.external) 
              template = (
                <NavItem eventKey= 'nav-' + key  href= route.path  key= key >
                  route.name
                </NavItem>
              );
             else 
              template = <HashNavItem eventKey= 'nav-' + key  name= route.name  to= route.path  key= key  />;
            
            return template;
          )
        
      </Nav>
    );
  

HashNavItem.jsx

import React,  Component  from "react";
import  NavItem  from 'react-bootstrap';
import  LinkContainer  from "react-router-bootstrap";

export default class HashNavItem extends Component 

  constructor(props) 
    super(props);
    // Atributes.
    this.hashFragment = '';
    this.observer = null;
    this.asyncTimerId = null;
    this.scrollFunction = null;
    // States.
    this.state = 
      key: props.eventKey,
      name: props.name,
      to: props.to
    
    // Methods.
    this.reset = this.reset.bind(this);
    this.getElAndScroll = this.getElAndScroll.bind(this);
    this.hashLinkScroll = this.hashLinkScroll.bind(this);
    this.handleClick = this.handleClick.bind(this);
  

  reset() 
    this.hashFragment = '';
    if (this.observer !== null) this.observer.disconnect();
    if (this.asyncTimerId !== null) 
      window.clearTimeout(this.asyncTimerId);
      this.asyncTimerId = null;
    
  

  getElAndScroll() 
    const element = document.getElementById(this.hashFragment);
    if (element !== null) 
      this.scrollFunction(element);
      this.reset();
      return true;
    
    return false;
  

  hashLinkScroll() 
    // Push onto callback queue so it runs after the DOM is updated
    window.setTimeout(() => 
      if (this.getElAndScroll() === false) 
        if (this.observer === null) 
          this.observer = new MutationObserver(this.getElAndScroll);
        
        this.observer.observe(document, 
          attributes: true,
          childList: true,
          subtree: true,
        );
        // if the element doesn't show up in 10 seconds, stop checking
        this.asyncTimerId = window.setTimeout(() => 
          this.reset();
        , 10000);
      
    , 0);
  

  handleClick(e) 
    this.reset();
    if (this.props.onClick) this.props.onClick(e);
    if (typeof this.props.to === 'string') 
      this.hashFragment = this.props.to
        .split('#')
        .slice(1)
        .join('#');
     else if (
      typeof this.props.to === 'object' &&
      typeof this.props.to.hash === 'string'
    ) 
      this.hashFragment = this.props.to.hash.replace('#', '');
    
    if (this.hashFragment !== '') 
      this.scrollFunction =
        this.props.scroll || (el =>
          el.scrollIntoView(this.props.smooth ?  behavior: 'smooth'  : undefined)
        );
      this.hashLinkScroll();
    
  

  render() 
    return (
      <LinkContainer to= this.state.to >
        <NavItem eventKey= this.state.key  key= this.state.key  onClick= this.handleClick > this.state.name  </NavItem>
      </LinkContainer>
    );
  

App.jsx

import React,  Component  from "react";
import  Router, Switch, Route  from 'react-router-dom';
import  createBrowserHistory  from 'history';

import MainNav from './MainNav/MainNav';
import Logo from './Logo/Logo';
import Footer from './Footer/Footer';
import Copyright from './Copyright/Copyright';
import HomePage from './HomePage/HomePage';
import AboutPage from './AboutPage/AboutPage';
import Error404 from './Error404/Error404';

import './App.css';

class App extends Component 
  render() 
    return (
      <Router history= createBrowserHistory() >
        <div>
          <MainNav />
          <Logo />
          <Switch>
            <Route exact path="/" component= HomePage  />
            <Route exact path="/about" component= AboutPage  />
            <Route exact path="/404" component= Error404  />
          </Switch>
          <Footer />
          <Copyright />
        </div>
      </Router>
    );
  


export default App;

有谁知道为什么首页总是被标记为活动

【问题讨论】:

【参考方案1】:

您应该使用 IndexLinkContainer 而不是 LinkContainer

Check here

【讨论】:

感谢您的提示!我会尝试的,我希望它有效! :)【参考方案2】:

既然你已经使用了react-bootstrap 包,那么你可以像这样解决你的问题:

import  NavLink  from "react-router-dom";
import  Nav  from "react-bootstrap";
    
<Nav>
    <Nav.Link as=NavLink exact to="/">
        Home
    </Nav.Link>
    <Nav.Link as=NavLink exact to="/about">
        About
    </Nav.Link>
</Nav>

这里的关键是将exact属性与Nav.Link组件一起使用,并将as属性设置为NavLink,如上面的sn-p所示。

Check the documentation of the NavLink's exact property 了解更多信息。

【讨论】:

【参考方案3】:

我相信这与您的路线有关(因此 react-router 不一定是 react-router-bootstrap)。我看到您在路线声明中添加了“精确”,但我也会尝试在您的声明中添加“严格”。在我正在开发的应用程序中,我必须这样做才能使我的高阶组件验证包装器正常工作。

如果这不起作用,那么我的猜测是您如何迭代路由数组以动态创建导航链接。通过您构建导航链接的方式,包清除活动状态可能存在问题。很抱歉我没有更具体的答案!我还没有获得 50+ 的声誉才能发表评论,因此必须提供一个有希望的有用答案。

【讨论】:

以上是关于SO react-router-bootstrap 活动链接无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

React-Bootstrap / React-Router-Bootstrap 中导航栏品牌的最佳实践

反应路由器,在 webpack 中使用 historyApiFallback true 重新加载 404

android应用自升级的时候so损坏

Android 逆向Android 中常用的 so 动态库 ( libdvm.so | libart.so | libandroid_runtime.so | libandroidfw.so )(代码

Android 逆向Android 中常用的 so 动态库 ( libdvm.so | libart.so | libandroid_runtime.so | libandroidfw.so )(代码

Android 逆向Android 中常用的 so 动态库 ( libm.so 数学函数动态库 | liblog.so 日志模块动态库 | libselinux.so 安全模块动态库 )(