2

Goal:
When you press one of the menulink, the classname 'active' should be applied next to classname 'default'

If you press another and new menu link, the previous classname 'active' should be removed and the new selected menulink should have 'active' next to classname 'default'.

In other words, one single 'active' only in the code.

Problem:
How do you solve it?

Info:
*Newbie in React JS
*Please take account that you might have many menulink.

Stackblitz:
https://stackblitz.com/edit/react-router-active-inline-style-single-empacx?file=src/App.js

Thank you!


import React from 'react';
import {
  BrowserRouter as Router,
  Routes,
  Route,
  NavLink,
} from 'react-router-dom';
import './style.css';

const Users = () => <div>Users</div>;
const Posts = () => <div>Posts</div>;

const App = () => {
  return (
    <div className="app">
      <Router>
        <div className="nav">
          <div className="default">
            <NavLink
              to="users"
              className={({ isActive }) =>
                '' + (isActive ? ' action' : ' inAction')
              }
            >
              Users
            </NavLink>
          </div>
          <br />
          <div className="default">
            <NavLink
              to="posts"
              className={({ isActive }) =>
                '' + (isActive ? ' action' : ' inAction')
              }
            >
              Posts
            </NavLink>
          </div>
        </div>
        <Routes>
          <Route path="users" element={<Users />} />
          <Route path="posts" element={<Posts />} />
        </Routes>
      </Router>
    </div>
  );
};

export default App;

@import url('https://fonts.googleapis.com/css2?family=Bree+Serif&display=swap');

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Bree Serif';
}

body {
  background: #f0f0f0;
}

a {
  text-decoration: none;
}

.app {
  background: #fff;
  margin: 25px auto;
  padding: 25px;
  max-width: 800px;
  width: 95%;
}

.nav {
  margin-bottom: 25px;
}

.nav a {
  border-radius: 4px;
  padding: 6px 10px;
  margin-right: 10px;
}

.nav a.active {
  color: #fff;
  background: #7600dc;
}
.nav a.inactive {
  font-style: italic;
}

.action {
  color: #fff;
  background: #7600dc;
}

.inAction {
  color: #545e6f;
  background: #f0f0f0;
}

.active {
  background-color: yellow;
}

.default {
  padding-top: 10px;
  padding-bottom: 10px;
}
HelloWorld1
  • 13,688
  • 28
  • 82
  • 145
  • You can use NavLink instead of parent div with default className and add children to NavLink with desired classes. Then do as mentioned in the answer: https://stackoverflow.com/questions/70539978/react-navlink-change-sub-element-according-to-isactive – Alex Tom Jun 04 '22 at 10:02

2 Answers2

0

If you are using NavLink, it has a property activeClassName where you can specify which class should be added when the link is active

Alex Shinkevich
  • 348
  • 1
  • 5
  • activeClassName is only active up to ver 17. It is not active in v18 – HelloWorld1 Jun 04 '22 at 09:13
  • In React-router v.6 activeClassName have been removed. See [here](https://reactrouter.com/docs/en/v6/upgrading/v5#remove-activeclassname-and-activestyle-props-from-navlink-) – Alex Tom Jun 04 '22 at 09:15
0

Here is my attempt according to Drew Reese solution:

<NavLink
    to="users"
    className={({ isActive }) =>
        'default' + (isActive ? ' active' : '')
    }
    children={({ isActive }) => {
        return (
            <div className={'' + (isActive ? ' action' : 'inAction')}>
                Users
            </div>
        );
     }}
></NavLink>

And in StackBlitz: https://stackblitz.com/edit/react-router-active-inline-style-single-arulrq?file=src%2FApp.js,src%2Fstyle.css

Some styling may differ...

Alex Tom
  • 221
  • 4
  • 12