Topic: MDBDropdownItem not working

Gerald Bailey premium asked 5 years ago


Expected behavior Selecting an item from the nav dropdown should direct user to the page referenced in the href tag.

Actual behavior Nothing happens! In addition, if I resize the widow, the hamburger menu toggle doesn't work at all. When using an onClick event such as the Logout, that works but I can't and should not have to use that for this.

Resources (screenshots, code snippets etc.)

App Code:

import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import jwt_decode from "jwt-decode";
import setAuthToken from "./utils/setAuthToken";
import { setCurrentUser, logoutUser } from "./actions/authActions";
import 'bootstrap/dist/css/bootstrap.min.css';

import { Provider } from "react-redux";
import store from "./store";

import Navigation from "./components/layout/Navigation";
import Footer from './components/layout/footer';
import Register from "./components/auth/Register";
import Login from "./components/auth/Login";
import Landing from "./components/layout/Landing";
import PrivateRoute from "./components/private-route/PrivateRoute";
import Dashboard from "./components/dashboard/Dashboard";
import Profile from "./components/dashboard/Profile";


// Check for token to keep user logged in
if (localStorage.jwtToken) {
    // Set auth token header auth
    const token = localStorage.jwtToken;
    setAuthToken(token);
    // Decode token and get user info and exp
    const decoded = jwt_decode(token);
    // Set user and isAuthenticated
    store.dispatch(setCurrentUser(decoded));

    // Check for expired token
    const currentTime = Date.now() / 1000; // to get in milliseconds
    if (decoded.exp < currentTime) {
        // Logout user
        store.dispatch(logoutUser());

        // Redirect to login
        window.location.href = "./login";
    }
}

class App extends Component {
    render() {
        return (
            <Provider store={store}>
                <Router>
                    <div className="App">
                        <Navigation />
                        <Route exact path="/" component={Landing} />
                        <Route exact path="/register" component={Register} />
                        <Route exact path="/login" component={Login} />
                        <Switch>
                            <PrivateRoute exact path="/dashboard" component={Dashboard} />
                            <PrivateRoute exact path="/profile" component={Profile} />
                        </Switch>
                        <Footer />
                    </div>
                </Router>
            </Provider>
        );
    }
}
export default App;

Navbar code:

import React, { Component } from "react";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { logoutUser } from "../../actions/authActions";

import {
    MDBNavbar,
    MDBNavbarBrand,
    MDBNavbarNav,
    MDBNavItem,
    MDBNavLink,
    MDBNavbarToggler,
    MDBCollapse,
    MDBDropdown,
    MDBDropdownToggle,
    MDBDropdownMenu,
    MDBDropdownItem,
    MDBIcon
} from "mdbreact";

import { BrowserRouter as Router } from "react-router-dom";
// import Routes from "./Routes";
import "../../App.css";
import logo from "../../assets/logo_white.png";

class Navigation extends Component {
    constructor(props) {
        super(props);
        this.state = {
            collapse: false,
            isWideEnough: false,
            isOpen: false,
            collapseID: ""
        };
    }

    toggleCollapse = collapseID => () =>
        this.setState(prevState => ({
            collapseID: prevState.collapseID !== collapseID ? collapseID : ""
        }));

    closeCollapse = collapseID => () => {
        window.scrollTo(0, 0);
        this.state.collapseID === collapseID && this.setState({ collapseID: "" });
    };

    onLogoutClick = e => {
        e.preventDefault();
        this.props.logoutUser();
    };

    onUpdateProfileClick = e => {
        e.preventDefault();
        console.log("Update Profile was clicked!");
    };

    render() {
        return (
            <MDBNavbar color="unique-color-dark" dark expand="md">
                <MDBNavbarBrand>
                    <img className="logo" src={logo} alt="1099house logo" />
                </MDBNavbarBrand>
                <MDBNavbarToggler onClick={this.toggleCollapse} />
                <MDBCollapse id="navbarCollapse3" isOpen={this.state.isOpen} navbar>
                    <MDBNavbarNav left>
                        <MDBNavItem>
                            <MDBNavLink to="/why">
                                <h6>Why</h6>
                            </MDBNavLink>
                        </MDBNavItem>
                        <MDBNavItem>
                            <MDBNavLink to="/credentials">
                                <h6>Credentials</h6>
                            </MDBNavLink>
                        </MDBNavItem>
                        <MDBNavItem>
                            <MDBNavLink to="mailto:support@1099house.com">
                                <h6>Contact Us</h6>
                            </MDBNavLink>
                        </MDBNavItem>
                    </MDBNavbarNav>
                    {!this.props.auth.isAuthenticated ? (
                        <MDBNavbarNav right>
                            <MDBNavItem>
                                <MDBNavLink to="/register">
                                    <h6>Register</h6>
                                </MDBNavLink>
                            </MDBNavItem>
                            <MDBNavItem>
                                <MDBNavLink to="/login">
                                    <h6>Sign In</h6>
                                </MDBNavLink>
                            </MDBNavItem>
                        </MDBNavbarNav>
                    ) : (
                        <MDBNavbarNav right>
                            <MDBNavItem>
                                <MDBDropdown >
                                    <MDBDropdownToggle nav caret>
                                        <MDBIcon icon="user" />
                                    </MDBDropdownToggle>
                                    <MDBDropdownMenu right>
                                        <MDBDropdownItem href="/profile">
                                            Update Profile
                                        </MDBDropdownItem>
                                        <MDBDropdownItem onClick={this.onLogoutClick} href="#!">
                                            Logout
                                        </MDBDropdownItem>
                                    </MDBDropdownMenu>
                                </MDBDropdown>
                            </MDBNavItem>
                        </MDBNavbarNav>
                    )}
                </MDBCollapse>
            </MDBNavbar>
        );
    }
}

Navigation.propTypes = {
    logoutUser: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
    auth: state.auth,
    errors: state.errors
});

export default connect(
    mapStateToProps,
    { logoutUser }
)(Navigation);

Jakub Chmura staff answered 5 years ago


Hi @Gerald Bailey,

MDBDropdownItem by default is a button, so there's no chance to use href='...' on this elementIf you want to use a DropdownItem as a link you should put inside MDBNavLink or just <a href='...'>... element. In your snippet, you tried to use href attribute in the button.

When it comes to toggle navbar when you resize the window, you write your own function to toggle hamburger menu what is a mistake because hamburger needs an isOpen: true/false value of the state to toggle (you use your own collapseID state). In this case, you need to use the toggleCollapse function from our documentation.

Look at this code sample. It should work fine.

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { logoutUser } from '../../actions/authActions';

import {
  MDBNavbar,
  MDBNavbarBrand,
  MDBNavbarNav,
  MDBNavItem,
  MDBNavLink,
  MDBNavbarToggler,
  MDBCollapse,
  MDBDropdown,
  MDBDropdownToggle,
  MDBDropdownMenu,
  MDBDropdownItem,
  MDBIcon
} from 'mdbreact';

import { BrowserRouter as Router } from 'react-router-dom';
// import Routes from "./Routes";
import '../../App.css';
import logo from '../../assets/logo_white.png';

class Navigation extends Component {
  constructor(props) {
    super(props);
    this.state = {
      collapse: false,
      isWideEnough: false,
      isOpen: false,
      collapseID: ''
    };
  }

  // toggleCollapse = collapseID => () =>
  //   this.setState(prevState => ({
  //     collapseID: prevState.collapseID !== collapseID ? collapseID : ''
  //   }));

  // closeCollapse = collapseID => () => {
  //   window.scrollTo(0, 0);
  //   this.state.collapseID === collapseID && this.setState({ collapseID: '' });
  // };

  toggleCollapse = () => {
    this.setState({ isOpen: !this.state.isOpen });
  }

  onLogoutClick = e => {
    e.preventDefault();
    this.props.logoutUser();
  };

  onUpdateProfileClick = e => {
    e.preventDefault();
    console.log('Update Profile was clicked!');
  };

  render() {
    return (
      <MDBNavbar color='unique-color-dark' dark expand='md'>
        <MDBNavbarBrand>
          <img className='logo' src={logo} alt='1099house logo' />
        </MDBNavbarBrand>
        <MDBNavbarToggler onClick={this.toggleCollapse} />
        <MDBCollapse id='navbarCollapse3' isOpen={this.state.isOpen} navbar>
          <MDBNavbarNav left>
            <MDBNavItem>
              <MDBNavLink to='/why'>
                <h6>Why</h6>
              </MDBNavLink>
            </MDBNavItem>
            <MDBNavItem>
              <MDBNavLink to='/credentials'>
                <h6>Credentials</h6>
              </MDBNavLink>
            </MDBNavItem>
            <MDBNavItem>
              <MDBNavLink to='mailto:support@1099house.com'>
                <h6>Contact Us</h6>
              </MDBNavLink>
            </MDBNavItem>
          </MDBNavbarNav>
          {!this.props.auth.isAuthenticated ? (
            <MDBNavbarNav right>
              <MDBNavItem>
                <MDBNavLink to='/register'>
                  <h6>Register</h6>
                </MDBNavLink>
              </MDBNavItem>
              <MDBNavItem>
                <MDBNavLink to='/login'>
                  <h6>Sign In</h6>
                </MDBNavLink>
              </MDBNavItem>
            </MDBNavbarNav>
          ) : (
            <MDBNavbarNav right>
              <MDBNavItem>
                <MDBDropdown>
                  <MDBDropdownToggle nav caret>
                    <MDBIcon icon='user' />
                  </MDBDropdownToggle>
                  <MDBDropdownMenu right>
                    <MDBDropdownItem>
                      <MDBNavLink to='/profile'>Update Profile</MDBNavLink>
                    </MDBDropdownItem>
                    <MDBDropdownItem>
                      <MDBNavLink to='#!'>Logout</MDBNavLink>
                    </MDBDropdownItem>
                  </MDBDropdownMenu>
                </MDBDropdown>
              </MDBNavItem>
            </MDBNavbarNav>
          )}
        </MDBCollapse>
      </MDBNavbar>
    );
  }
}

Navigation.propTypes = {
  logoutUser: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
  auth: state.auth,
  errors: state.errors
});

export default connect(
  mapStateToProps,
  { logoutUser }
)(Navigation);

Best regards,

Kuba


Gerald Bailey premium commented 5 years ago

My code is a direct copy variation of the documentation which uses href, so that's why I did it that way. Perhaps there should be some clarification in the documentation then? I'll try your example, thanks for the help!


Jakub Chmura staff commented 5 years ago

Thank you for your feedback!

We definitely need to check our documentation then.

If there is anything else I could do for you do not hesitate to ask me. I'll be happy to help you.

Best Regards,

Kuba



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • ForumUser: Premium
  • Premium support: Yes
  • Technology: MDB React
  • MDB Version: 4.21.1
  • Device: Mac
  • Browser: Chrome
  • OS: 10.15
  • Provided sample code: No
  • Provided link: No