Жирное активное меню после обновления страницы - PullRequest
1 голос
/ 24 июня 2019

У меня приложение было написано с React + Redux и Antdesign.Мое приложение представляет собой приложение для панели инструментов.Поэтому я использовал макет в Ant design https://ant.design/components/layout/

Когда я нажимаю на боковые меню, активное меню выделяется жирным шрифтом, и это нормально.Но мне нужно, когда я обновляю страницу, она проверяет и обнаруживает маршрут и пункт меню, связанный с жирным шрифтом.

У меня есть компонент Боковая панель , в котором есть состояние.Внутри него в componentDidMount я вызываю функцию, которая отправляет действие из mapDispatchToProps.Редуктор меняет состояние.Но в кодах HTML в defaultSelectedKeys я не могу установить количество активных меню.

Компонент Sidebar.js:

import React from 'react';
import { render } from 'react-dom';
import { connect } from 'react-redux'
import { Switch, BrowserRouter, Route, Link } from 'react-router-dom';

// antd
import { Layout, Breadcrumb, Menu, Icon } from 'antd';
const { Header, Content, Footer, Sider } = Layout;

// Helpers
import { Alert } from '../helpers/notifications';

// Components
import Home from '../components/Home';
// import Header from '../components/Header';
import NotFound from '../components/NotFound';
import PostsEditor from '../components/Posts/PostsEditor';

// Actions
import { setRouteActiveFlag } from '../actions/ui.action'

class Sidebar extends React.Component {

    componentDidMount () {
      const routes = {
        '/'       : 1,
        '/posts'  : 2,
        '/logout' : 3
      }

      this.props.detectActiveRoute(setRouteActiveFlag({
        routes:routes, 
        path:window.location.pathname
      }))
    }


    render() {

        const { selectedRoute } = this.props;
        console.log(selectedRoute);

        return (
            <div>
              <Layout>
                <Sider
                  style={{
                    overflow: 'auto',
                    height: '100vh',
                    position: 'fixed',
                    left: 0,
                  }} 
                  breakpoint="lg"
                  collapsedWidth="0"
                  onBreakpoint={broken => {
                    console.log(broken);
                  }}
                  onCollapse={(collapsed, type) => {
                    console.log(collapsed, type);
                  }}
                >
                  <div className="logo" >
                    Logo <br/><br/><br/>
                  </div>
                  <Menu theme="dark" mode="inline"  style={{ lineHeight: '64px' }} defaultSelectedKeys={[selectedRoute.toString() || '1']}>
                    <Menu.Item key="1">
                      <Link to="/" style={{ color:'#fff' }}>
                        <Icon type="user" />
                        <span className="nav-text">Home</span>
                      </Link>
                    </Menu.Item>
                    <Menu.Item key="2">
                      <Link to="/posts" style={{ color:'#fff' }}>
                        <Icon type="user" />
                        <span className="nav-text">Posts</span>
                      </Link>
                    </Menu.Item>
                    <Menu.Item key="3">
                      <a href="/logout" style={{ color:'#fff' }}>
                        <Icon type="user" />
                        <span className="nav-text">Logout</span>
                      </a>
                    </Menu.Item>
                  </Menu>
                </Sider>
                <Layout style={{ marginLeft: 200 }}>
                  <Content style={{ margin: '24px 16px 0', overflow: 'initial'}}>

                      <Breadcrumb style={{ margin: '0 0 20px 0' }}>
                        <Breadcrumb.Item>Home</Breadcrumb.Item>
                        <Breadcrumb.Item>List</Breadcrumb.Item>
                        <Breadcrumb.Item>App</Breadcrumb.Item>
                      </Breadcrumb>

                      <div style={{ padding: 24, background: '#fff', minHeight: 360 }}>
                        <Switch>
                            <Route path="/" exact component={Home} />
                            <Route path="/posts/:id?" component={PostsEditor} />
                            <Route component={NotFound}/>
                        </Switch>
                        <Alert stack={ { limit: 3 } } />
                      </div>

                  </Content>

                  <Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
                </Layout>
              </Layout>
            </div>
        );
    }
}

const mapStateToProps = (state, ownProps) => {
    return {
      state: state,
      props: ownProps,
      selectedRoute:state.ui.selectedRoute || 1
    }
}

const mapDispatchToProps = (dispatch, ownProps) => {
    return {
      detectActiveRoute: (obj) => dispatch(obj)
    }
}


export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Sidebar)

ui.action.js

export const setRouteActiveFlag = (payload = 'global') => ({
  type: actions.SET_ROUTE_ACTIVE_FLAG,
  payload
});

ui.reducer.js

import { handleActions } from 'redux-actions';
import Immutable from 'seamless-immutable';
import * as actions from '../consts/action-types';


const initialState = Immutable({
  requests: {},
  selectedRoute:{}
});


export default handleActions({
  [actions.SET_ROUTE_ACTIVE_FLAG]: (state, action) => {
    if (action.payload.routes && action.payload.path && action.payload.routes[ action.payload.path ]) {
        return state.set('selectedRoute', action.payload.routes[ action.payload.path ])
    }else{
        return state.set('selectedRoute', 1)
    }
  }
}, initialState);



Пожалуйста, помогите мне найти лучшие и простые практики.

Ответы [ 2 ]

2 голосов
/ 24 июня 2019

Нет необходимости использовать redux, просто используйте react-router, чтобы получить текущий путь и передать его defaultSelectedKeys.

<Menu defaultSelectedKeys={[this.props.location.pathname]}>
  ...
  .....
</Menu>

Посмотрите на этот ответ , если вы не знаете, как получить путь

0 голосов
/ 22 июля 2019

Вы можете добавить любой CSS в ваше меню, если вы добавите класс таким образом.

<MenuItem className={ (this.props.location.pathname==='/yourRoute')? 'active' : '' } >

</MenuItem>

В случае, если вы получаете какую-либо неопределенную ошибку, вы можете использовать 'withRouter' HOC

таким образом.

В вашем компоненте, где вы хотите получить этот объект, вы сначала импортируете

import {withRouter} from 'react-router-dom';

тогда вы можете экспортировать его таким образом.

export default withRouter(YourComponent);

Итоговый код может выглядеть примерно так:

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

class Menu extends Component {

   render(){

     const {pathname} = this.props.location;

     return (
        <Fragment>
            <div id="sidebar-menu" className="sidebar-menu">

                    <ul>
                        <li className={(pathname==='/dashboard' || pathname==='/')?'active':''}> 
                            <Link to="/dashboard">Dashboard</Link>
                        </li>

                        <li className={(pathname==='/properties')?'active':''}> 
                            <Link to="/properties">Properties</Link>
                        </li>
                    </ul>

            </div>
        </Fragment>
     );

     }

}
export default withRouter(Menu);
...