3

I've been using Mantine.Dev for a project and got stuck in an issue where I want that the NavBar only appears in an specific route, like the images below:

enter image description here

enter image description here

What I need to do is that when the route is set to "/locations" the NavBar appear on the right side, and for all the other routes, the NavBar will be hidden.

I've tried this: (active={location.pathname === '/home'}) and got a recommendation from the Mantine guys to use <AppShell navbar={location.pathname === '/home' && <Navbar />} />.

When I use their suggestions, I get an error saying that the navbar prop won't accept a boolean and a React element together.

The error I've been seeing is:

TS2322: Type 'false | Element' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>> | undefined'.
  Type 'boolean' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>>'.

App.tsx

import './App.scss';
import { Routes, Route, Link, useLocation } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from 'react-query';
import { MantineProvider, AppShell } from '@mantine/core';
import React = require('react');

// //COMPONENTS
import AppHeader from './Components/AppHeader';
import LocationNavbar from './Components/LocationNavbar';

// // ROUTES
import Locations from './Location';
import People from './People';
import WhoToCall from './WhoToCall';

const queryClient = new QueryClient();

export default function App() {
  // const location = useLocation();
  const location = useLocation();
  console.log(location.pathname);
  console.log(location.key);

  return (
    <QueryClientProvider client={queryClient}>
      <MantineProvider withGlobalStyles withNormalizeCSS>
        <AppShell
          navbarOffsetBreakpoint="sm"
          header={<AppHeader />}
          navbar={location.pathname === '/location' ? <LocationNavbar /> : null}
        >
          <Routes>
            <Route path="/location" element={<Locations />} />
            <Route path="/people" element={<People />} />
            <Route path="/who-to-call" element={<WhoToCall />} />
            <Route path="/" element={<People />} />
          </Routes>
        </AppShell>
      </MantineProvider>
    </QueryClientProvider>
  );
}

Any ideas?!

Stackblitz Link: https://stackblitz.com/edit/react-ts-bybprx?file=App.tsx

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Pam Gaiguer
  • 56
  • 2
  • 6
  • Does this help answer your question? https://stackoverflow.com/a/69999387/8690857 – Drew Reese Sep 02 '22 at 04:02
  • It's the same idea, but im using [Mantine.Dev](https://mantine.dev/) as my framework and I believe that the error is coming from some particular syntax from it. – Pam Gaiguer Sep 02 '22 at 04:07
  • So, you are not using `react-router-dom`? Please edit your post to include a more complete and comprehensive [mcve] so we've more context what that code is doing and what you are trying to accomplish. I've not ever heard of mantine.dev, so more information will be helpful. – Drew Reese Sep 02 '22 at 04:07
  • the stackblitz link is throwing an error. please provide a working [mre] – nullptr Sep 02 '22 at 04:33

1 Answers1

2

It seems you are on the correct track, but with some minor issues.

index.tsx

There needs to be a router component wrapping the App to provide a routing context so App can access the location object via the useLocation hook.

import * as React from 'react';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';

const rootElement = document.getElementById('root');
const root = createRoot(rootElement);

root.render(
  <StrictMode>
    <Router>
      <App />
    </Router>
  </StrictMode>
);

App.tsx

The error is saying that the navbar prop needs a valid value type assigned to is, and booleans are not acceptable. Use a ternary operator to return the LocationNavbar component or null, and ensure you are comparing the pathname to a route you actually render, i.e. "/locations". "/locations" is the target link path in AppHeader.

<Anchor component={Link} variant="link" to="/locations" color="gray">
  Locations
</Anchor>

...

export default function App() {
  const { pathname } = useLocation();

  return (
    <QueryClientProvider client={queryClient}>
      <MantineProvider withGlobalStyles withNormalizeCSS>
        <AppShell
          navbarOffsetBreakpoint="sm"
          header={<AppHeader />}
          navbar={pathname === '/locations' ? <LocationNavbar /> : null}
        >
          <Routes>
            <Route path="/locations" element={<Locations />} />
            <Route path="/people" element={<People />} />
            <Route path="/who-to-call" element={<WhoToCall />} />
            <Route path="/" element={<People />} />
          </Routes>
        </AppShell>
      </MantineProvider>
    </QueryClientProvider>
  );
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181