【问题标题】:Header/Footer navigation react-router-dom and antd menu and router problems页眉/页脚导航 react-router-dom 和 antd 菜单和路由器问题
【发布时间】:2018-02-04 23:01:59
【问题描述】:

我正在开发一个 reactjs 应用程序 - 我创建了两个菜单 - 页眉/页脚 - 当我在页面上导航时,我注意到“活动”状态存在错误。

// 当前存在的问题

  1. 当到达主页时,主页链接在标题菜单上处于活动状态,但当单击页脚菜单 - 隐私 - 隐私链接处于活动状态,但标题链接在应该停用时仍然处于活动状态。
  2. 此外,当进入一个不存在的页面时,例如键入 /home2 - 它应该会跳到错误页面,但它没有 - 是什么干扰了路由器?

// 登陆主页——主页处于活动状态

// 登陆隐私 - 页脚中的隐私处于活动状态 - 但页眉中的主页也仍然处于活动状态。

// Header.js

import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import { Row, Col, Menu, Icon, Alert } from 'antd'

const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup;

// this is a class because it needs state
class Header extends Component {

  state = {
    current: 'home',
  }

  handleClick = (e) => {
    console.log('click ', e);
    this.setState({
      current: e.key,
    });
  }

  componentDidMount() {    

  }

  render() {
    return (
      <Menu
        onClick={this.handleClick}
        selectedKeys={[this.state.current]}
        mode="horizontal"
      >
        <Menu.Item key="home">
          <Link to="/home" rel="noopener noreferrer">Home</Link>
        </Menu.Item>
        <Menu.Item key="account">
          <Link to="/account" rel="noopener noreferrer">Account</Link>
        </Menu.Item>
      </Menu>
    )
  }
}

export default Header

// 页脚.js

import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import { Row, Col, Menu, Icon, Alert } from 'antd'

const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup;

// this is a class because it needs state
class Footer extends Component {

  state = {
    current: 'home',
  }

  handleClick = (e) => {
    console.log('click ', e);
    this.setState({
      current: e.key,
    });
  }

  componentDidMount() {    

  }

  render() {
    return (
      <Menu
        onClick={this.handleClick}
        selectedKeys={[this.state.current]}
        mode="horizontal"
      >
        <Menu.Item key="about">
          <Link to="/about" rel="noopener noreferrer">About</Link>
        </Menu.Item>
        <Menu.Item key="terms">
          <Link to="/terms" rel="noopener noreferrer">Terms of Service</Link>
        </Menu.Item>
        <Menu.Item key="privacy">
          <Link to="/privacy" rel="noopener noreferrer">Privacy Policy</Link>
        </Menu.Item>
      </Menu>
    )
  }
}

export default Footer

// router.js

import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom'
import createBrowserHistory from 'history/createBrowserHistory'
import { Provider } from 'react-redux'
import { createStore, compose } from 'redux'

// components
import Login from './components/Login/Login'

import Home from './components/Home/Home'
import Account from './components/Account/Account'

import About from './components/About/About'
import Terms from './components/Terms/Terms'
import Privacy from './components/Privacy/Privacy'

import Error from './components/Error/Error'

import Header from './components/Header/Header'
import Footer from './components/Footer/Footer'

const history = createBrowserHistory()

//const store = createStore(rootReducer, compose(
const store = createStore(compose(
  typeof window === 'object' && typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : (f) => f
  )
)

// we can pass the lang files as props to the routes
// we should have a nested route inside service here to show the other services page

class Routes extends Component {
  render () {
    return (
      <Provider store={store}>
        <Router history={history}>
          <div className='off-canvas-wrap' data-offcanvas>
            <div className='inner-wrap'>
              <Header transparent />
              <Switch>
                <Route path='/home' component={Home} />
                <Route path='/account' component={Account} />

                <Route path='/about' component={About} />
                <Route path='/terms' component={Terms} />
                <Route path='/privacy' component={Privacy} />

                <Route path='/login' component={Login} />
                <Route path='/' component={Login} />
                <Route component={Error} />
              </Switch>
              <Footer transparent />
            </div>
          </div>
        </Router>
      </Provider>
    )
  }
}

export default Routes

【问题讨论】:

  • 你的 react 路由器版本是多少?
  • "react-router-dom": "^4.2.2",
  • --是否只是因为页眉/页脚组件如果不在页面上需要取消选择?

标签: reactjs react-router antd


【解决方案1】:

如果您使用的是react router 4

您可以使用NavLink。它提供了activeClassNameactiveStyle 选项来添加 类和activeStyle

activeClassName

<NavLink to="/about" activeClassName="selected">about </NavLink>

activeStyle

<NavLink
  to="/about"
  activeStyle={{
    color: 'red'
   }}
>about</NavLink>

另外,当进入一个不存在的页面时,比如输入 /home2 - 它应该跳到错误页面,但它没有 - 是什么在路由器中干扰了这个?

问题就在这里:

<Route path='/' component={Login} />

如果没有匹配的路由,它将渲染到Login 组件而不是Error 组件

您必须将exact 添加到Route 以获得Error 组件的404 行为。

这样做的正确方法。

<Route exact path='/' component={Login} />

【讨论】:

  • - 但它使用的是 antd 菜单 -- 我想对于页脚我可以使用 NavLink -- 但对于页眉使用菜单 -- 我还想将页眉菜单配置为在响应时压缩
  • --我明白了--是的,我把它作为 / 用于登录页面 -- 但你说我应该为登录页面做确切的路径 -- 好的,我应该只是 /login - 并在 / 上使用重定向? -- 我只希望他们在未登录时跳转到登录页面 -- 否则我想他们会去主页
  • should I have it just /login - and use a redirect on / ?yes.Jst 如果没有登录会跳到/ogin
  • --好的-你能做一个演示吗-如果登录/未记录弹跳-从'react-router'导入{路由,重定向} ( 登录 ? ( ) : ( ) }/>
【解决方案2】:

问题出在您的路由组件这行出现问题:-

 <Route path='/' component={Login} />

一定是这样的

<Route exact path='/' component={Login} />

如果您不使用exact 属性,则每次它都会与路由/ 匹配。所以你需要添加一个exact 关键字来避免这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-14
    • 2022-08-11
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-21
    相关资源
    最近更新 更多