0
votes

I'm trying to redo my menu with React Hooks and here's my latest attempt.

The only issue I have is that when I click sub-menu-click, all the sub menu opens.

How can I make it so that only the child is open when the parent (i.e. Item 1) is clicked?

Thank you.

import React, { useState } from 'react';

export default () => {
    const [menuOpen, setMenuOpen] = useState(false);
    const [subMenuOpen, setSubMenuOpen] = useState(false);
    const toggleClassName = menuOpen ? 'is-open' : '';

    const data = useStaticQuery(graphql`
        query {
            site {
                siteMetadata {
                    title
                }
            }
        }
    `);
    return (
        <Layout>
            <Menu>
                <div class="menu-left">
                    <Link to="/">{data.site.siteMetadata.title}</Link>
                </div>
                <Hamburger
                    className={toggleClassName}
                    onClick={() => setMenuOpen(!menuOpen)}
                >
                    <span></span>
                    <span></span>
                    <span></span>
                </Hamburger>
                <div class="menu-right">
                    <ul className={toggleClassName}>
                        <li class="menu-item has-children">
                            <Link to="/">
                                Item 1
                            </Link>
                            <div
                                class={`sub-menu-click`}
                                onClick={() => setSubMenuOpen(!subMenuOpen)}
                            >
                                <span></span>
                            </div>
                            <ul
                                class={`sub-menu && ${
                                    subMenuOpen ? 'is-open' : ''
                                }`}
                            >
                                <li class="menu-item">Sub-Item 1</li>
                                <li class="menu-item">Sub-Item 2</li>
                                <li class="menu-item">Sub-Item 3</li>
                            </ul>
                        </li>
                        <li class="menu-item has-children">
                            <Link to="/">
                                Item 2
                            </Link>
                            <div
                                class={`sub-menu-click`}
                                onClick={() => setSubMenuOpen(!subMenuOpen)}
                            >
                                <span
                                    class={`${subMenuOpen ? 'is-open' : ''}`}
                                ></span>
                            </div>
                            <ul
                                class={`sub-menu && ${
                                    subMenuOpen ? 'is-open' : ''
                                }`}
                            >
                                <li class="menu-item">Sub-Item 1</li>
                                <li class="menu-item">Sub-Item 2</li>
                                <li class="menu-item">Sub-Item 3</li>
                            </ul>
                        </li>
                    </ul>
                </div>
            </Menu>
        </Layout>
    );
};

1

1 Answers

0
votes

The simplest solution to this to move the SubMenu to a different component and let it have it's own state.

const SubMenu = () => {
  const [subMenuOpen, setSubMenuOpen] = useState(false);
  return (
    <li class="menu-item has-children">
     <Link to="/">
          Item 1
     </Link>
     <div
        class={`sub-menu-click`}
        onClick={() => setSubMenuOpen(!subMenuOpen)}
      >
          <span></span>
      </div>
      <ul
          class={`sub-menu && ${
              subMenuOpen ? 'is-open' : ''
          }`}
      >
          <li class="menu-item">Sub-Item 1</li>
          <li class="menu-item">Sub-Item 2</li>
          <li class="menu-item">Sub-Item 3</li>
      </ul>
  </li>
  )
}

and render this component in place for SubMenu in Menu component.

In case you need to control the opening of SubMenu from the Menu component, you have an array of subMenuIds currently open or a single ID according to your use case.