0

I have added a basic react-bootstrap navbar and set the NavLinks up as react-router .Links. When I click on the links they do not show as active. They will only show as active on the second click of the same link. The router is set up in the app.js file. How do I get them to show as active on first click?

Here is the code for my NavBar component:

import { Navbar, Nav, Container } from 'react-bootstrap'
import { Link } from 'react-router-dom'
import LanguageSwitchSelector from './LanguageSwitchSelector'
import Logout from './Logout'
import { useSelector } from 'react-redux'
import text from '../data/text'

const NavBar = () => {
  const currentLanguage = useSelector((state) => state) //retrieves current language from store
  if(!currentLanguage) {
    return null
  }

  const code = currentLanguage.code
  return (
    <div>
      <Navbar collapseOnSelect expand="lg" bg="dark" variant="dark">
        <Container>
          <Navbar.Toggle aria-controls="responsive-navbar-nav" />
          <Navbar.Collapse id="responsive-navbar-nav">
            <Nav className="mr-auto">
              <Nav.Link as={Link} to="/dashboard">
                {text[code]['dashboard']}
              </Nav.Link>
              <Nav.Link as={Link} to="/competitions">
                {text[code]['competitions']}
              </Nav.Link>
              <Nav.Link as={Link} to="/tracks">
                {text[code]['tracks']}
              </Nav.Link>
            </Nav>
          </Navbar.Collapse>
          <LanguageSwitchSelector />
          <Logout text={text[code]['logout']} />
        </Container>
      </Navbar>
    </div>
  )
}

export default NavBar

App.js

import React, { useState, useEffect } from 'react'
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Redirect,
} from 'react-router-dom'
import { useDispatch } from 'react-redux'
import Login from './components/Login'
import Dashboard from './components/Dashboard'
import ManageCompetitions from './components/ManageCompetitions'
import ManageTracks from './components/ManageTracks'
import { initLanguage } from './reducers/languageReducer'

const App = () => {
  const [user, setUser] = useState()
  const dispatch = useDispatch()

  useEffect(() => {
    const loggedInUser = localStorage.getItem('user')
    const savedLanguage = localStorage.getItem('lang')
    if (savedLanguage) {
      const foundLanguage = JSON.parse(savedLanguage)
      dispatch(initLanguage(foundLanguage))
      console.log('found language ', foundLanguage)
    } else {
      dispatch(initLanguage())
    }
    if (loggedInUser) {
      const foundUser = JSON.parse(loggedInUser)
      setUser(foundUser)
      console.log(foundUser)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  return (
    <Router>
      <Switch>
        <Route path="/login">
          <Login />
        </Route>
        <Route path="/dashboard">
          <Dashboard />
        </Route>
        <Route path="/competitions">
          <ManageCompetitions />
        </Route>
        <Route path="/tracks">
          <ManageTracks />
        </Route>
        <Route path="/">
          {user ? <Redirect to="/dashboard" /> : <Redirect to="/login" />}
        </Route>
      </Switch>
    </Router>
  )
}

export default App

1 Answers1

0
import React, { useState } from 'react';
import { Navbar, Nav, Container } from 'react-bootstrap';
export default function App() {
  const [id, setID] = useState('test1');
  const handleActive = (id) => {
    setID(id);
  };
  return (
    <div>
      <Navbar collapseOnSelect expand="lg" bg="dark" variant="dark">
        <Container>
          <Navbar.Collapse id="responsive-navbar-nav">
            <Nav className="mr-auto">
              <Nav.Link
                onClick={() => handleActive('test1')}
                to="/test1"
                style={{ color: id === 'test1' ? 'red' : '' }}
              >
                test1
              </Nav.Link>
              <br />
              <Nav.Link
                onClick={() => handleActive('test2')}
                id={'test2'}
                to="/test2"
                style={{ color: id === 'test2' ? 'red' : '' }}
              >
                test2
              </Nav.Link>
              <br />
              <Nav.Link
                onClick={() => handleActive('test3')}
                id={'test3'}
                to="/test3"
                style={{ color: id === 'test3' ? 'red' : '' }}
              >
                test3
              </Nav.Link>
            </Nav>
          </Navbar.Collapse>
        </Container>
      </Navbar>
    </div>
  );
}

You can simple take a state of id which unique the tab or menu you click on and set the state of that menu then in style or class you can use ternary check please have a look above code or copy and run.

  • Thanks for your answer. When I implement your code it keeps test1 link as red no matter which link I click on and if I click on the other links they show as bootstrap active style and test1 still stays red. Here is the code after edit: – Matthew Everitt Oct 07 '21 at 04:20
  • ` handleActive('test1')} as={Link} to="/dashboard" style={{ color: id === 'test1' ? 'red' : '' }}> {text} ` – Matthew Everitt Oct 07 '21 at 04:25
  • These were the changes I made to each Nav.Link element and I added the handleActive function and the setId state. – Matthew Everitt Oct 07 '21 at 04:33
  • Yes i see you need to take link as a state as i did with id. onClick change the link and on link state you can change active as well and style too. – stack overflow Oct 10 '21 at 12:09