Conditional render Navigation

98 Views Asked by At

Hi I need conditional render my navigation. I use Gatsby and GraphQl. I have Navigation Component and depends on route in which it is I need render different Navigation. The problem is I can not make conditional useStateStatic hook. I've made two diffrent Navigation in my source it is DatoCMS,but I can not query for it.

const Navigation = () => {
  const pathName = window.location.pathname;
  const data = useStaticQuery(
    graphql`
      {
        datoCmsNavigation(sectionId: { eq: "navigation" }) {
          sectionId
          logo {
            url
            alt
          }
          menuItem {
            id
            name
            href
          }
        }
      }
    `
  );

  const {
    datoCmsNavigation: { sectionId, logo, menuItem },
  } = data;

  return (
    <NavBar id={sectionId}>
      <NavBarLogoWrapper>
        <a href="/">
          <img src={logo.url} alt={logo.test} />
        </a>
      </NavBarLogoWrapper>

      <NavBarList>
        {menuItem.map((item, index) => (
          <NavBarItem key={index}>
            <a href={item.href}> {item.name.toLowerCase()}</a>
          </NavBarItem>
        ))}
      </NavBarList>
    </NavBar>
  );
};

Here is my Navigation component. Does anyone has Idea how can I deal with it ?

1

There are 1 best solutions below

0
On

Your approach will fail in gatsby build since window (and other global objects) are not available during the SSR. You don't need a useState hook in your scenario, you just need to know which page is actually the user seeing.

Top-level components (pages) in Gatsby own the location property, which allows you to know a bunch of data, including the current page. You can pass that data to your Navigation component in order to make your comparison. For example:

const Blog = ({location, someOtherDestructuredProps}) => {

   return <section>
     <Navigation currentPage={location.pathname}/>
     <OtherComponent />
   </section>
}

Then, in your Navigation component:

const Navigation = ({currentPage ="/"}) => {
  const pathName = window.location.pathname;
  const data = useStaticQuery(
    graphql`
      {
        datoCmsNavigation(sectionId: { eq: "navigation" }) {
          sectionId
          logo {
            url
            alt
          }
          menuItem {
            id
            name
            href
          }
        }
      }
    `
  );

  const {
    datoCmsNavigation: { sectionId, logo, menuItem },
  } = data;

  return (
    <NavBar id={sectionId}>
      <NavBarLogoWrapper>
        <a href="/">
          <img src={logo.url} alt={logo.test} />
        </a>
      </NavBarLogoWrapper>

      <NavBarList>
        {menuItem.map((item, index) => {
         
         if(currentPage == '/blog') return <DifferentNavBar />
         return <NavBarItem key={index}>
            <a href={item.href}> {item.name.toLowerCase()}</a>
          </NavBarItem>
        })}
      </NavBarList>
    </NavBar>
  );
};

Among minor changes, the important part is to set a default value for the currentPage (in case it's missing) and the change of the map loop in order to return different navigation bars. Of course, tweak it to adapt it to your needs and requeriments.