How to change MDNavBar item to active dynamically?


Topic: How to change MDNavBar item to active dynamically?

Ady G asked 5 years ago

I would like to highlight the active Navbar item dynamically when using React-Router-Dom.

I am using a typical Navigation component, with MDBNavItem/MDBNavLink, and the main app containing the routes (at the moment).

Could anyone give me a few pointers on this?


App.js is defined as:

function App() {
return (
    <React.Fragment>
        <Router>

        <Navigation/>

        <MDBContainer>
            <Switch>
                <Route path="/home">
                    <Home/>
                </Route>
                <Route path="/colour">
                    <Set/>
                </Route>

                <Route path="/">
                    <Home/>
                </Route>
            </Switch>
        </MDBContainer>

        </Router>
    </React.Fragment>
);

}

export default App;

Navigation component is defined as:

class Navigation extends Component {

state = {
    isOpen:'',
};

constructor( props ) {
    super( props );
    this.setState( {
        isOpen : false,
    } );
}

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


render() {
    return (
        <React.Fragment>
            <MDBNavbar color="yellow" light expand="md" className='mb-3'>
                <MDBNavbarBrand href="/">
                    <strong className="">App Name</strong>
                </MDBNavbarBrand>
                <MDBNavbarToggler onClick={ this.toggleCollapse }/>
                <MDBCollapse id="navbarCollapse3" isOpen={ this.state.isOpen } navbar>
                    <MDBNavbarNav left>
                        <MDBNavItem active>
                            <MDBNavLink to="/home">Home</MDBNavLink>
                        </MDBNavItem>
                        <MDBNavItem >
                            <MDBNavLink to="/colours">Colours</MDBNavLink>
                        </MDBNavItem>
                        <MDBNavItem>
                            <MDBNavLink to="/pens">Pens</MDBNavLink>
                        </MDBNavItem>
                        <MDBNavItem>
                            <MDBDropdown>
                                <MDBDropdownToggle nav caret>
                                    <span className="mr-2">Members</span>
                                </MDBDropdownToggle>
                                <MDBDropdownMenu>
                                    <MDBDropdownItem href="#!">Profile</MDBDropdownItem>
                                    <MDBDropdownItem href="#!">Login</MDBDropdownItem>
                                    <MDBDropdownItem href="#!">Logout</MDBDropdownItem>
                                    <MDBDropdownItem href="#!">Register</MDBDropdownItem>
                                </MDBDropdownMenu>
                            </MDBDropdown>
                        </MDBNavItem>
                    </MDBNavbarNav>
                    <MDBNavbarNav right>
                        <MDBNavItem>
                            <MDBFormInline waves>
                                <div className="md-form my-0">
                                    <input className="form-control mr-sm-2"
                                           type="text"
                                           placeholder="Search"
                                           aria-label="Search"/>
                                </div>
                            </MDBFormInline>
                        </MDBNavItem>
                    </MDBNavbarNav>
                </MDBCollapse>
            </MDBNavbar>
        </React.Fragment>
    );
}

}

export default Navigation;


Konrad Stępień staff commented 5 years ago

Hi @Ady G, Can you check @Mike.Thomson answer and tell me if the problem still exists?


Using Hooks and Context you can do as follows - set the active attribute on '' when ever the route changes. For example here is a sample navbar component - see active={activePath === 'routePath'}

import React, { useState, useContext } from 'react'
import AppContext from '../../context/appContext'
import {
  MDBNavbar,
  MDBNavbarBrand,
  MDBNavbarNav,
  MDBNavItem,
  MDBNavLink,
  MDBNavbarToggler,
  MDBCollapse,
  MDBDropdown,
  MDBDropdownToggle,
  MDBDropdownMenu,
  MDBDropdownItem,
  MDBIcon
} from 'mdbreact'

const NavBar = () => {
  const appContext = useContext(AppContext)
  const [navOpen, toggleOpen] = useState(false)
  const closeNav = () => {
    toggleOpen(false)
  }

  // Destructure properties from App Level State
  const { activePath } = appContext

  return (
    <MDBNavbar fixed='top' color='white' light expand='lg'>
      {/* fixed='top' */}
      <MDBNavbarBrand>
        {/* <strong className='white-text'>TrustPoint</strong> */}
        <img src='/images/trustpoint.png' alt='TRUSTPOINT' />
      </MDBNavbarBrand>
      <MDBNavbarToggler onClick={() => toggleOpen(!navOpen)} />
      <MDBCollapse id='navbarCollapse3' isOpen={navOpen} navbar>
        <MDBNavbarNav left>
          <MDBNavItem active={activePath === '/'}>
            <MDBNavLink onClick={closeNav} to='/'>
              Dashboard
            </MDBNavLink>
          </MDBNavItem>
          <MDBNavItem active={activePath === '/business'}>
            <MDBNavLink onClick={closeNav} to='/business'>
              Business
            </MDBNavLink>
          </MDBNavItem>
          <MDBNavItem active={activePath === '/owners'}>
            <MDBNavLink onClick={closeNav} to='/owners'>
              Owners
            </MDBNavLink>
          </MDBNavItem>
          <MDBNavItem active={activePath === '/suppliers'}>
            <MDBNavLink onClick={closeNav} to='/suppliers'>
              Suppliers
            </MDBNavLink>
          </MDBNavItem>
          <MDBNavItem active={activePath === '/properties'}>
            <MDBNavLink onClick={closeNav} to='/properties'>
              Properties
            </MDBNavLink>
          </MDBNavItem>
          <MDBNavItem active={activePath === '/rentals'}>
            <MDBNavLink onClick={closeNav} to='/rentals'>
              Rentals
            </MDBNavLink>
          </MDBNavItem>
          <MDBNavItem active={activePath === '/banking'}>
            <MDBNavLink onClick={closeNav} to='/banking'>
              Banking
            </MDBNavLink>
          </MDBNavItem>
          <MDBNavItem active={activePath === '/reconcile'}>
            <MDBNavLink onClick={closeNav} to='/reconcile'>
              Reconcile
            </MDBNavLink>
          </MDBNavItem>
          <MDBNavItem active={activePath === '/transactions'}>
            <MDBNavLink onClick={closeNav} to='/transactions'>
              Transactions
            </MDBNavLink>
          </MDBNavItem>
          <MDBNavItem active={activePath === '/reports'}>
            <MDBNavLink onClick={closeNav} to='/reports'>
              Reports
            </MDBNavLink>
          </MDBNavItem>
          <MDBNavItem active={activePath === '/monthend'}>
            <MDBNavLink onClick={closeNav} to='/monthend'>
              Month End
            </MDBNavLink>
          </MDBNavItem>
        </MDBNavbarNav>
        <MDBNavbarNav right>
          <MDBNavItem>
            <MDBDropdown>
              <MDBDropdownToggle nav caret>
                <MDBIcon icon='user' />
              </MDBDropdownToggle>
              <MDBDropdownMenu className='dropdown-default'>
                <MDBDropdownItem href='#!'>Profile</MDBDropdownItem>
                <MDBDropdownItem href='#!'>Logout</MDBDropdownItem>
              </MDBDropdownMenu>
            </MDBDropdown>
          </MDBNavItem>
        </MDBNavbarNav>
      </MDBCollapse>
    </MDBNavbar>
  )
}

export default NavBar

In My case, the App.js looks like this (Notr the appContext.setActivePath

import React, { useEffect, useContext } from 'react'
import { Route, Switch } from 'react-router-dom'
import AppContext from './context/appContext'
import { useLocation } from 'react-router'

import Dashboard from './components/pages/Dashboard'
import Business from './components/pages/Business'
import Owners from './components/pages/Owners'
import Suppliers from './components/pages/Suppliers'
import Properties from './components/pages/Properties'
import Banking from './components/pages/Banking'
import Receipts from './components/pages/Receipts'
import Reconcile from './components/pages/Reconcile'
import Transactions from './components/pages/Transactions'
import Reports from './components/pages/Reports'
import NotFound from './components/pages/NotFound'

const Routes = () => {
  const appContext = useContext(AppContext)
  let location = useLocation()

  useEffect(() => {
    appContext.setActivePath(location.pathname)
    // eslint-disable-next-line
  }, [location])

  return (
    <Switch>
      <Route exact path='/' component={Dashboard} />
      <Route exact path='/business' component={Business} />
      <Route exact path='/owners' component={Owners} />
      <Route exact path='/suppliers' component={Suppliers} />
      <Route exact path='/properties' component={Properties} />
      <Route exact path='/banking' component={Banking} />
      <Route exact path='/receipts' component={Receipts} />
      <Route exact path='/reconcile' component={Reconcile} />
      <Route exact path='/transactions' component={Transactions} />
      <Route exact path='/reports' component={Reports} />
      <Route path='*' component={NotFound} />
    </Switch>
  )
}

export default Routes

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
  • User: Free
  • Premium support: No
  • Technology: MDB React
  • MDB Version: 4.22.0
  • Device: Any
  • Browser: All
  • OS: Any
  • Provided sample code: No
  • Provided link: No