汉堡菜单切换状态问题

时间:2021-07-20 20:23:11

标签: reactjs next.js

目前我正在处理 Next.js 博客项目,我想实现汉堡菜单,但是当我点击汉堡按钮时没有任何反应。这是我的第一个项目。我提供源代码。

这是 Layout 组件:

import Backdrop from "../BackDrop/Backdrop";
import Navigation from "../Navigation/Navigation";
import SideDrawer from "../SideDrawer/SideDrawer";
import { useState } from "react";

function Layout(props) {
  const [sideDrawerOpen, setSideDrawerOpen] = useState(false);

  function toogleClickHandler() {
    setSideDrawerOpen((prevState) => {
      return { sideDrawerOpen: !prevState.sideDrawerOpen };
    });
  }

  let sideDrawer;
  let backdrop;

  if (sideDrawerOpen) {
    sideDrawer: <SideDrawer />;
    backdrop: <Backdrop />;
  }
  return (
    <div style={{ height: "100%" }}>
      <Navigation drawerClickHandler={toogleClickHandler} />
      {sideDrawer}
      {backdrop}
      <main style={{ marginTop: "64px" }}>{props.children}</main>
    </div>
  );
}

export default Layout;

Layout 组件将所有组件包装在 _app.js 文件中:

import "../styles/globals.css";
import Layout from "../Components/Layout/Layout";
function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

export default MyApp;

这些是 Layout 组件使用的三个组件:

Navigation.js 组件:

import Link from "next/link";
import Logo from "../Logo/Logo";
import classes from "./Navigation.module.css";
import DrawerToggleButton from "../SideDrawer/DrawerToggleButton";

function Navigation(props) {
  return (
    <header className={classes.header}>
      <nav className={classes.nav}>
        <div>
          <DrawerToggleButton click={props.drawerClickHandler} />
        </div>
        <div>
          <Link href="/">
            <a>
              <Logo />
            </a>
          </Link>
        </div>
        <div className={classes.spacer}></div>
        <div className={classes.navItems}>
          <ul>
            <li>
              <Link href="/">
                <a>Home</a>
              </Link>
            </li>
            <li>
              <Link href="/allposts">
                <a>All Posts</a>
              </Link>
            </li>
            <li>
              <Link href="/featuredposts">
                <a>Featured Posts</a>
              </Link>
            </li>
            <li>
              <Link href="/Products">
                <a>Products</a>
              </Link>
            </li>
          </ul>
        </div>
      </nav>
    </header>
  );
}
export default Navigation;

这是 SideDrawer 组件:

import Link from "next/link";
import classes from "./SideDrawer.module.css";

const SideDrawer = (props) => {
  return (
    <nav className={classes.sideDrawer}>
      <ul>
        <li>
          <Link href="/">
            <a>Home</a>
          </Link>
        </li>
        <li>
          <Link href="/allposts">
            <a>All Posts</a>
          </Link>
        </li>
        <li>
          <Link href="/featuredposts">
            <a>Featured Posts</a>
          </Link>
        </li>
        <li>
          <Link href="/products">
            <a>Products</a>
          </Link>
        </li>
      </ul>
    </nav>
  );
};

export default SideDrawer;

这是 Backdrop 组件:

import classes from "./Backdrop.module.css";

function Backdrop(props) {
  return <div className={classes.backdrop}></div>;
}

export default Backdrop;

使用此 NavigationDrawerToggleButton 组件。这是 DrawerToggleButton 组件:

import classes from "./DrawerToggleButton.module.css";

const DrawerToggleButton = (props) => (
  <button className={classes.button} onClick={props.click}>
    <div className={classes.line} />
    <div className={classes.line} />
    <div className={classes.line} />
  </button>
);

export default DrawerToggleButton;

2 个答案:

答案 0 :(得分:0)

您需要在这里解决三个问题。首先,您的导航组件正在寻找 props.click,但您的布局组件正在发送一个名为 drawerClickHandler 的道具。此外,您应该传递鼠标事件处理程序或处理鼠标事件并调用单击函数。最后,当您想在 setSideDrawerOpen 中切换状态时,您应该获取之前的状态并使用它来设置/切换值:

// Layout Component
import Backdrop from "../BackDrop/Backdrop";
import Navigation from "../Navigation/Navigation";
import SideDrawer from "../SideDrawer/SideDrawer";
import { useState } from "react";

function Layout(props) {
  const [sideDrawerOpen, setSideDrawerOpen] = useState(false);

  function toogleClickHandler() {
    // Use the previous state to set the new state
    setSideDrawerOpen((prevState) => !prevState);
  }

  let sideDrawer;
  let backdrop;

  if (sideDrawerOpen) {
    sideDrawer: <SideDrawer />;
    backdrop: <Backdrop />;
  }
  return (
    <div style={{ height: "100%" }}>
      // Let's pass this prop to the Navigation - see the change I make in that component
      <Navigation drawerClickHandler={toogleClickHandler} />
      {sideDrawer}
      {backdrop}
      <main style={{ marginTop: "64px" }}>{props.children}</main>
    </div>
  );
}

export default Layout;

// Navigation Component
import classes from "./DrawerToggleButton.module.css";

// Two changes here. First, use the correct prop name. Second, `onClick`
// should be a function that calls your prop/function
const DrawerToggleButton = (props) => (
  <button className={classes.button} onClick={() => props.drawerClickHandler}>
    <div className={classes.line} />
    <div className={classes.line} />
    <div className={classes.line} />
  </button>
);

export default DrawerToggleButton;

答案 1 :(得分:-1)

问题可能出在您的 setSideDrawerOpen 上。

取而代之的是:

function toogleClickHandler() {
    setSideDrawerOpen((prevState) => {
      return { sideDrawerOpen: !prevState.sideDrawerOpen };
    });
  }

试试这个?

function toogleClickHandler() {
    setSideDrawerOpen(!sideDrawerOpen);
  }