Discover the step-by-step guide on showcasing and activating the main navigation menu item and sub navigation menu item simultaneously within a single page using React Material UI Tabs

Within my React component representing the header, I am utilizing Material UI Tabs from Material UI's documentation to construct a primary navigation menu. Instead of displaying tab content, I have decided to incorporate React router links:

    <Tabs value={location.pathname}>
      {(items || []).map((item) => (
        <Tab
          key={item.url}
          label={item.title}
          value={item.url}
          href={item.url}
          disableRipple
        />
      ))}
    </Tabs>

Furthermore, on the same page, I have also implemented Material UI Tabs for a secondary menu.

The path to the main navigation menu item is: /example-path. Upon navigating to this route, the respective menu items are highlighted and display as active.

In situations where a secondary menu item shares the same route as the highlighted primary menu item /example-path, both menus will be highlighted and show an active state simultaneously.

If I were to click on another secondary menu item, only that specific item would be highlighted under its designated path /example-path/tab-two.

I am curious about managing the highlighting of both the parent main navigation menu and various secondary menu items simultaneously. How can I achieve this?

Answer №1

The Header module must match only the root path segment, while the Submenu module can compare the entire URL pathname. Keep in mind that if there are additional sub-routes, the Submenu module will need to check the first two segments.

Instead of having the Tab components display a raw anchor tag <a>, they should render a Link component. This allows the router to handle the navigation action, instead of triggering a page request from the browser and reloading the entire application.

Header

import { Tabs, Tab } from "@material-ui/core";
import { Link, useLocation } from "react-router-dom";

const Header = () => {
  const { pathname } = useLocation();
  const base = `/${pathname.slice(1).split("/").shift()}`;

  return (
    <Tabs value={base}>
      <Tab component={Link} to="/" label="Home" key="/" value="/" />
      <Tab
        component={Link}
        to="/about"
        label="About"
        key="/about"
        value="/about"
      />
      <Tab
        component={Link}
        to="/dashboard"
        label="Dashboard"
        key="/dashboard"
        value="/dashboard"
      />
    </Tabs>
  );
};

export default Header;

Submenu

import { Tabs, Tab } from "@material-ui/core";
import { Link, useLocation } from "react-router-dom";

const Submenu = () => {
  const { pathname } = useLocation();

  return (
    <Tabs value={pathname}>
      <Tab
        component={Link}
        to="/about/about-one"
        label="About sub one"
        key="1"
        value="/about/about-one"
      />
      <Tab
        component={Link}
        to="/about/about-two"
        label="About sub two"
        key="2"
        value="/about/about-two"
      />
    </Tabs>
  );
};

export default Submenu;

App Ensure that the routes within the Switch are ordered in reverse order of path specificity, so that more specific paths are matched before less specific ones.

<Router>
  <Layout>
    <Switch>
      <Route path="/about/about-one">
        <AboutOne />
      </Route>
      <Route path="/about/about-two">
        <AboutTwo />
      </Route>
      <Route path="/about">
        <About />
      </Route>
      <Route path="/dashboard">
        <Dashboard />
      </Route>
      <Route path="/">
        <Home />
      </Route>
    </Switch>
  </Layout>
</Router>

https://codesandbox.io/s/tabs-subnavigation-forked-pwtf21?fontsize=14&hidenavigation=1&module=%2Fsrc%2FHeader.tsx&theme=dark

https://i.stack.imgur.com/EFFc5.png

To update for handling submenu tabs on the root route "/", you'll need to implement a workaround. Check that the URL path is not one of the main root routes to override the base Tabs value to be exactly "/" instead of one of the "/home-section/*" sub-routes using the matchPath utility function.

Example:

import { Tabs, Tab } from "@material-ui/core";
import { Link, useLocation, matchPath } from "react-router-dom";

const Header = () => {
  const { pathname } = useLocation();
  const base = `/${pathname.slice(1).split("/").shift()}`;

  const isNotHome = ["/about", "/dashboard"].some((path) =>
    matchPath(pathname, path)
  );

  return (
    <Tabs value={isNotHome ? base : "/"}>
      <Tab component={Link} to="/" label="Home" key="1" value="/" />
      <Tab component={Link} to="/about" label="About" key="2" value="/about" />
      <Tab
        component={Link}
        to="/dashboard"
        label="Dashboard"
        key="3"
        value="/dashboard"
      />
    </Tabs>
  );
};

export default Header;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The input field in Ckeditor dialogs becomes inaccessible when the editor is placed within a modal interface

Currently, I am incorporating material-ui-next dialog with CKEditor as the editor placed within the modal. In order to add LaTeX text, I have utilized the MathJax plugin. However, I have encountered an issue where I am unable to focus the input field to pr ...

Abruptly shut down: Stripe/Apple Pay

We have a React-based web application that is set up to accept payments through Stripe integration. However, we are facing an issue where the Apply Pay option popup closes abruptly before users can complete the transaction. We have ensured that the domai ...

What causes fs to produce an error when routing to a new page, yet refreshing the page resolves the issue?

Concern: I have developed a NextJs application with 4 input fields, each connected to a predefined options list read in as a json file within the project. The user can select two fields and then proceed to a search page by clicking a button. From the sear ...

The button component is unresponsive

An app was developed with a component containing signin and signup buttons on the right side. However, there is an issue where the Sign up button is not clickable. Below is the code snippet for the component => import React from "react"; expo ...

Leveraging NestJs Libraries within Your Nx Monorepo Main Application

I am currently part of a collaborative Nx monorepo workspace. The setup of the workspace looks something like this: https://i.stack.imgur.com/zenPw.png Within the structure, the api functions as a NestJS application while the data-access-scripts-execute ...

Encoding URLs for LoopBack applications

I am experiencing an issue with the filter I have: { "fields": {"goal":true,"amountPledged": true,"title": true},"where": {"title": {"like":`%${this.state.searchText}%`}} } The this.state.searchText value is bio. According to my understanding, it should ...

Steps for updating state in AWS Cognito userhandler function

I'm currently working on a React project that requires authorization through AWS Cognito. I've been able to successfully obtain the ID token by following the documentation, but I'm unsure of how to update the state in the onsuccess callback. ...

Utilizing custom types in React with TypeScript and Prop-Types

Currently, I am working with a string type literal that looks like this: type MyType = 'str1' | 'str2' | 'str3'. I need one of my props to only accept this specific type, but I'm struggling to specify this in PropTypes. ...

Ways to bring GIFs into NextJS

I am currently working on my portfolio website using Nextjs and I would like to incorporate gifs into the site. However, I have been struggling to figure out how to do so. Below is the code that I have been working with: https://i.stack.imgur.com/zjoiD.pn ...

Server-side rendering issue arises post updating to Material UI 5 (with Next.js)

After upgrading my app with server-side rendering (SSR) from version 4 to version 5 of MUI, I encountered an issue. Despite following the official migration guide, I found that when JavaScript was disabled, the page rendered as raw HTML without any CSS sty ...

Can ReactJS and jQuery be used together or are they mutually exclusive?

As a beginner in the world of ReactJS, I am intrigued by how this library essentially handles all DOM node rendering without any need for interference from other libraries like jQuery. However, this does pose a challenge as many convenient jQuery plugins ...

The Drawer element is not displaying the desired styling as expected

I have a simple question about styling a Drawer component in React. When I use the sx property to add styles, they are being applied to the parent block of the Drawer instead of the Drawer itself. As a result, the styles are not appearing as expected on th ...

The React component that generates HTML is not rendering correctly

I have a function that generates an unordered list export const generateListMarkup = (data) => { var ul = document.createElement('ul') let labels = {Data1: 'Data 1 name', Data2: 'Data 2 name', Data3: 'Data ...

What steps can be taken to ensure that the email input remains on the current page, eliminating the need for the user to re-enter their email address?

Initially, I implemented the reset password feature using AWS Amplify by creating two separate forms: one for forgotPassword, which takes usernames, and another for forgotPasswordSubmit to update the password. The setup involved multiple routes, and the pa ...

Using React with Material-UI for creating interactive tabs and drawers

I am encountering an issue with opening a drawer within the tab that is currently open using React and Material-UI. Although I can successfully open the drawer, it displays in the first tab instead. Initially, I suspected a problem with my component struct ...

Endless [React Native] onFlatList onEndReached callback invoked

Attempting to create my debut app using ReactNative with Expo, I've hit a snag with FlatList. The components are making infinite calls even when I'm not at the end of the view. Another issue might be related; across multiple screens, the infinite ...

Is there a way to universally modify variant, color, style, and other properties for Material-UI components across the entire application?

Is there a way to simplify this code block: <Button variant="contained" color="primary" style={{textTransform: "none"}} > Description </Button> Can I achieve the same result with just: <Button> Description </Button> W ...

axios: prevent automatic sorting of objects according to keys

When using axios, I am receiving an API response. To send the sorted API response based on name, I use the following endpoint: http://localhost:8000/api/ingredients/ordering=name The actual object received from my server looks like this: { 2:{"id":2 ...

Attempting to transfer information from a JSON file to a Netflix-inspired platform

Images I am currently working on integrating data from my json file export const products = [ { name: 'iPhone 11', image: '/assets/images (7).jpeg', time: '1 hour 14mins', age: '+16&apo ...

Troubles with CSS in MUI Component Integration

How can I successfully implement a vertical timeline using Material UI in React? I've set it up, but the CSS isn't functioning as expected. Is there an error in my implementation? List of Dependencies: "@emotion/react": "^11.11.1& ...