How to display different styled Navbars on different pages in ReactJS?

3.4k views Asked by At

I have three different Navbars. Each of them is a different component.

  • <PublicNavbar /> ,which is for public pages such as LandingPage, DiscoverPage etc.
  • <AccessNavbar /> ,which is for SignInPage, SignUppage, VerificationPage etc.
  • <PrivateNavbar /> , which is for private pages such as NewCampaignPage etc.

How can I show them properly? If a user is logged in, I want to replace DiscoverPage's PublicNavbar with PrivateNavbar.

import React from "react";
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import "semantic-ui-css/semantic.min.css";
import "./App.css";
import PublicNavbar from "./components/Navbar/PublicNavbar";
import AccessNavbar from "./components/Navbar/AccessNavbar";
import PrivateNavbar from "./components/Navbar/PrivateNavbar";
import Footer from "./components/Footer";
import LandingPage from "./pages/LandingPage";
import SignIn from "./pages/SIgnInPage";
import DiscoverPage from "./pages/DiscoverPage";
import SignUp from "./pages/SignUpPage";
import Verification from "./pages/VerificationPage";
import Registration from "./pages/RegistrationPage";
import RegistrationComplete from "./pages/RegistrationCompletePage";
import NewCampaign from "./pages/NewCampaignPage";

function App() {
  return (
    <Router>
      <div>
        <div id="container">
          <div id="main">
            <Switch>
              <Route path="/" exact component={LandingPage} />
              <Route path="/discover" component={DiscoverPage} />
              <Route path="/signIn" component={SignIn} />
              <Route path="/signUp" component={SignUp} />
              <Route path="/verification" component={Verification} />
              <Route path="/registration" component={Registration} />
              <Route
                path="/registration-complete"
                component={RegistrationComplete}
              />
              <Route path="/new-campaign" component={NewCampaign} />
            </Switch>
          </div>
        </div>
        <Footer />
      </div>
    </Router>
  );
}
export default App;

Sample Navbar code:

import React from "react";

const PublicNavbar = () => {
  return (
    <nav className="navbar navbar-expand-lg bg-white">
      <div className="container-fluid navbar-container">
        <a className="navbar-brand abs nav-bar-title" href="#">
          AshoDaanKori
        </a>
        <button
          className="navbar-toggler ms-auto custom-toggler"
          type="button"
          data-bs-toggle="collapse"
          data-bs-target="#collapseNavbar"
        >
          <span className="navbar-toggler-icon"></span>
        </button>
        <div className="navbar-collapse collapse" id="collapseNavbar">
          <ul className="navbar-nav ms-auto">
            <li className="nav-item active">
              <a
                className="nav-link"
                href=""
                data-bs-target="#myModal"
                data-bs-toggle="modal"
              >
                About
              </a>
            </li>
            <li className="nav-item active">
              <a
                className="nav-link"
                href=""
                data-bs-target="#myModal"
                data-bs-toggle="modal"
              >
                How it works
              </a>
            </li>
            <li className="nav-item active">
              <a
                className="nav-link"
                href=""
                data-bs-target="#myModal"
                data-bs-toggle="modal"
              >
                Discover
              </a>
            </li>
          </ul>
          <a
            className="nav-link navbar-btn"
            href=""
            data-bs-target="#myModal"
            data-bs-toggle="modal"
          >
            Start Campaign
          </a>
        </div>
      </div>
    </nav>
  );
};
export default PublicNavbar;

2

There are 2 answers

0
restricted-beam On

Create a new Navbar component named something like NavBarController. While calling the navbar controller component pass in the "Type" as prop. Type should be a state and should change depending on the user status.

<NavBarController type={1}></NavBarController>

Let NavBarController handle whichever navbar you want to display out of your three navbars (where type will be 1,2 or 3).

Your NavBarController will return something like this:

return (props.type===1?<PublicNavbar/>
:props.type===2?<AccessNavbar/>
:props.type===3?<PrivateNavbar/>)
0
Fahim Shahriyar On

Solved it by conditional rendering. Without creating multiple Navbar components, I created one and changed the inner elements based on condition.

const Navbar = ({ isAuthenticated }) => {
  return (
    <nav
      className={`autohide navbar navbar-expand-lg bg-white ${
        isAuthenticated ? "private-navbar" : ""
      }`}
    >
      <div className="container-fluid navbar-container">
        <NavHashLink className="navbar-brand abs nav-bar-title" to="/">
          AshoDaanKori
        </NavHashLink>
        <button
          className="navbar-toggler ms-auto custom-toggler"
          type="button"
          data-bs-toggle="collapse"
          data-bs-target="#main_nav"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span className="navbar-toggler-icon"></span>
        </button>

        {isAuthenticated ? (
          <div className="collapse navbar-collapse" id="main_nav">
            <ul className="navbar-nav ms-auto">
              <li className="nav-item active">
                <NavHashLink to="/my-fundraisers" className="nav-link">
                  My fundraisers
                </NavHashLink>
              </li>
            </ul>
            <Link to="/start-campaign" className="nav-link navbar-btn">
              Start a new campaign
            </Link>

            {/* User profile */}
            <div className="btn-group nav-item">
              <button
                type="button"
                className="btn "
                data-bs-toggle="dropdown"
                data-bs-display="static"
                aria-expanded="false"
                style={{ padding: "0" }}
              >
                <i aria-hidden="true" className="user circle huge icon"></i>
              </button>
              <ul className="dropdown-menu dropdown-menu-end">
                <li>
                  <h3
                    style={{
                      textAlign: "center",
                      fontSize: 18,
                      fontWeight: 600,
                      color: "#6E6E6E",
                    }}
                  >
                    {userInfo.fullName || "User"}
                  </h3>
                </li>
                <li>
                  <hr className="dropdown-divider" />{" "}
                </li>
                <li>
                  <Link className="dropdown-item" to="/account">
                    Account Settings
                  </Link>
                </li>
                <li>
                  <Link
                    className="dropdown-item"
                    to="#"
                  >
                    Sign Out
                  </Link>
                </li>
              </ul>
            </div>
          </div> //If authenticated, rendered PrivateNavbar elements
        ) : (
          <div className="collapse navbar-collapse" id="main_nav">
            <ul className="navbar-nav ms-auto">
              <li className="nav-item active">
                <NavHashLink
                  smooth
                  to="/#our-story-section"
                  className="nav-link"
                >
                  About
                </NavHashLink>
              </li>
              <li className="nav-item active">
                <NavHashLink to="/how-it-works" className="nav-link">
                  How it works
                </NavHashLink>
              </li>
              <li className="nav-item active">
                <NavHashLink to="/discover" className="nav-link">
                  Discover
                </NavHashLink>
              </li>
            </ul>
            <NavHashLink to="/sign-in" className="nav-link navbar-btn">
              START CAMPAIGN
            </NavHashLink>
          </div> //If not authenticated, rendered PublicNavbar elements
        )}
      </div>
    </nav>
  );
};
export default Navbar;