reactjs页眉/页脚菜单处理 - 当前页面和活动状态

时间:2017-08-28 11:21:30

标签: reactjs redux react-router antd

我正在开发一个reactjs应用程序 - 标题菜单是一个antd菜单,页脚链接是NavLinks ..我的问题源于正确设置菜单 - 我试图提供路由级别的CURRENT页面 - 并将其提供给页眉/页脚组件。

应用程序不稳定 - 我刷新主页上的页面是活动的 - 如果我刷新页面上的条款它不选择主页链接 - 但页脚中的链接未设置为选择 - - 并且组件之间的通信不存在 - 如果我点击它就选择帐户 - 然后转到页脚链接等。

这是应该或可以由redux商店处理的东西 - 如果是这样,如何实现这个?正常?

对此有何建议?

const mapStateToProps = (state) => {
  return {
    current_page: state.current
  }
}

const { bool, string, func } = React.PropTypes
Header.propTypes = {
  current_page: string
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Header)) 

代码目前看起来像这样。 http://jsfiddle.net/0ht35rpb/105/

// 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 {


  constructor (props) {
    super(props)
    this.state = {
      current: window.location.pathname.substr(1),
    }
  }

  render () {
    const loggedIn = 1;
    const current = this.state.current;

    return (
      <Provider store={store}>
        <Router history={history}>
          <div className='off-canvas-wrap' data-offcanvas>
            <div className='inner-wrap'>
              <Header transparent current={current} />
              <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 exact path="/" render={() => ( loggedIn ? ( <Home/> ) : ( <Redirect to="/login"/> ) )} />

                <Route component={Error} />
              </Switch>
              <Footer transparent current={current} />
            </div>
          </div>
        </Router>
      </Provider>
    )
  }
}

export default Routes

// Header.js

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

// assets
//import LogoImage from '../../../img/-logo_red.gif'

// css
import './header.scss'

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

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

  constructor (props) {
    super(props)
    console.log(this.props.current)
    this.state = {
      isHamburgerOpen: false,
      current: this.props.current,
    }
    this.toggleHamburgerIcon = this.toggleHamburgerIcon.bind(this)
  }

  toggleHamburgerIcon () {
    this.setState(prevState => ({
      isHamburgerOpen: !prevState.isHamburgerOpen
    }))
  }

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

  componentDidMount() {    
    console.log('did mount')
    // window.location.pathname.substr(1)
  }

  /*
  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>
    )
  }
  */


  render () {
    console.log('this.state', this.state)
    console.log('this.props.current', this.props.current)

    return (
      <div>

        <nav className={`HeaderLandingNavOffcanvas ${this.state.isHamburgerOpen ? 'show' : ''}`}>
          <h1 className='display-none nocontent'>Site navigation</h1>
          <i className='anticon anticon-close closeOffsiteMenu' onClick={this.toggleHamburgerIcon}/>
          <div className='row grid__row--offset--30'>
            <div className='small-58 small-centered columns'>
              <Menu
                   mode='inline'
                   onClick={this.handleClick}
                   selectedKeys={[this.state.current]}
                >
                  <Menu.Item key="home" className='menu-gtm-service'>
                    <Link to="/home" rel="noopener noreferrer">
                      Home
                    </Link>
                  </Menu.Item>
                  <Menu.Item key="account" className='menu-gtm-service'>
                    <Link to="/account" rel="noopener noreferrer">
                      Account
                    </Link>
                  </Menu.Item>
                </Menu>
            </div>
          </div>
        </nav>

        {/* Large Header */}
        <header className='ant-design-header transition show-for-large-up transparent'>
          <Row align='middle' type='flex' className='header-row-offset' style={{height: '100%'}}>
            <Col span={24}>
              <Row align='middle' type='flex' className='header-row-offset' style={{maxWidth: '1250px', marginLeft: 'auto', marginRight: 'auto'}}>
                <Col xs={10} sm={6} md={6}>
                  {/*
                  <Link to='/'>
                    <img className='-logo transition' src={LogoImage} alt='logo' />
                  </Link>
                  */}
                </Col>
                <Col xs={0} sm={0} md={18}>
                  <Menu
                    className='show-for-large-up'
                    mode='horizontal'
                    onClick={this.handleClick}
                    selectedKeys={[this.state.current]}
                    style={{ float: 'right', marginTop: '5px' }}
                  >
                    <Menu.Item key="home" className='menu-gtm-service'>
                      <Link to="/home" rel="noopener noreferrer">
                        Home
                      </Link>
                    </Menu.Item>
                    <Menu.Item key="account" className='menu-gtm-service'>
                      <Link to="/account" rel="noopener noreferrer">
                        Account
                      </Link>
                    </Menu.Item>
                  </Menu>
                </Col>

                <Col xs={{ span: 4, offset: 10 }} sm={{ span: 4, offset: 14 }} md={0}>
                  <div style={{ float: 'right', height: '50px', marginRight: '10px' }}>
                    <div className={`hamburger--elastic hamburger hamburger_nav_button right-off-canvas-toggle ${this.state.isHamburgerOpen ? 'is-active' : ''}`} onClick={this.toggleHamburgerIcon} style={{ marginTop: '5px' }}>
                      <span className='hamburger-box'>
                        <span className='hamburger-inner' />
                      </span>
                    </div>
                  </div>
                </Col>
              </Row>

            </Col>
          </Row>
        </header>


      </div>
    )
  }

}

export default Header

// Footer.js

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

// css
import './footer.scss'

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

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

  componentDidMount() {    

  }

  render() {
    console.log('this.props.current footer', this.props.current)

    return (
      <footer className='main-footer'>
        <ul>
          <li>
            <NavLink
              to="/about"
              activeClassName="selected">about
            </NavLink>
          </li>
          <li>
            <NavLink
              to="/terms"
              activeClassName="selected">terms
            </NavLink>
          </li>
          <li>
            <NavLink
              to="/privacy"
              activeClassName="selected">privacy
            </NavLink>
          </li>
        </ul>
      </footer>
    )
  }
}

export default Footer

0 个答案:

没有答案