如何在 NextJS 中使用 useState 显示或隐藏 div?

Ale*_*ton 4 reactjs next.js

我 \xe2\x80\x99m 是 React 新手,但尝试构建一个响应式网站,其中包含 \xe2\x80\x9cdesktop header\xe2\x80\x9d 和 \xe2\x80\x9cmobile header\xe2\x80\x9d用户单击菜单图标切换并在用户单击关闭图标时关闭。\nI\xe2\x80\x99m 显然做错了,但 can\xe2\x80\x99t 似乎找出问题所在,我相信 NextJS 不知道要打开或关闭什么。

\n

**注意:I\xc2\xb4m 使用 TailwindCSS,这是一个将在索引页上呈现的组件

\n

我的代码看起来像这样(简化,没有所有内容):

\n
import React, { useState } from 'react'\nimport Image from 'next/Image'\n\nfunction header() {\n\nconst \\[mobile__Header, setMobile__Header\\] = useState(false)\n\nconst showMobile__Header = () =\\> setMobile__Header(!mobile__Header)\n\nreturn (\\<div\\>\n\n        {/* mobile header */}\n    \n        <div className='absolute flex flex-col w-screen h-screen place-content-between bg-white text-black p-5 z-50'>\n    \n            <div className='flex items-center justify-between'>\n    \n                {/* Left Logo */}\n    \n                <div className='cursor-pointer'>\n                    \n                </div>\n    \n                {/* close icon */}\n    \n                <div className='cursor-pointer' onClick={showMobile__Header}>\n                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">\n                    <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />\n                    </svg>\n                </div>\n    \n            </div>\n    \n            {/* nav links */}\n    \n            <div className='flex'>\n                <div className='flex flex-col text-xl space-y-3'>\n                    \n                </div>\n            </div>\n    \n            {/* Social links and languaje changer */}\n    \n            <div className='flex justify-between font-light'>\n                <div>\n                    <a className="link" href="">EN</a>\n                </div>\n    \n                <div className='flex flex-col'>\n                   \n                </div>\n    \n            </div>\n    \n        </div>\n        \n        {/* desktop header */}\n    \n        <header className="flex w- px-10 py-1 justify-between">\n                \n    \n             <div className="flex">\n    \n                {/* Left Logos */}\n    \n                <div className="flex md:hidden cursor-pointer">\n                    \n                </div>\n    \n                <div className="hidden md:flex cursor-pointer">\n                    \n                </div>\n    \n            </div>\n    \n            \n            <div className="flex items-center">\n    \n                {/* Menu icon toggle */}\n    \n                <div className='flex md:hidden cursor-pointer' onClick={showMobile__Header}>\n    \n                    <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>\n                    <path strokeLinecap="round" strokeLinejoin="round" d="M4 6h16M4 12h16M4 18h16" />\n                    </svg>\n    \n                </div>\n    \n                {/* Right Nav Links and language changer */}\n    \n                <div className="space-x-4 px-5 py-5 hidden md:flex ">\n                    \n                </div>\n    \n            </div>\n    \n            \n    \n        </header>\n    \n    \n    \n        \n    </div>\n    )}\n    export default header\n
Run Code Online (Sandbox Code Playgroud)\n

Sea*_*n W 6

您有许多 HTML/CSS 问题,例如定位和元素结构。

免费的 tailwindui 示例是一个值得参考的可靠示例。它具有很好的过渡和可访问性,我在示例中将其删除。它还使用headlessuiHeroicons,两者都是由 TW 团队构建的。TW 菜单组件在内部处理状态,因此您将无法看到其示例中的逻辑。

下面的响应式示例基于上面引用的版本,但没有外部依赖项。

import { useState } from "react";

const Navbar = () => {
  const [isOpen, setOpen] = useState(false);
  const toggleMenu = () => setOpen(!isOpen);

  return (
      <header className="relative bg-white">
        <div className="max-w-7xl mx-auto px-4 sm:px-6">
          <div className="flex justify-between items-center border-b-2 border-gray-100 py-6 md:justify-start md:space-x-10">
            <div className="flex justify-start lg:w-0 lg:flex-1">
              <a href="#">
                <span className="h-8 w-auto sm:h-10">LOGO</span>
              </a>
            </div>
            <div className="-mr-2 -my-2 md:hidden">
              <button
                onClick={toggleMenu}
                className="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500"
              >
                Open
              </button>
            </div>
            <nav className="hidden md:flex space-x-10">
              <a href="#" className="text-base font-medium text-gray-500 hover:text-gray-900">
                About
              </a>
            </nav>
          </div>
        </div>
        {isOpen && (
          <div className="absolute top-0 inset-x-0 p-2 transition transform origin-top-right md:hidden">
            <div className="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 bg-white divide-y-2 divide-gray-50">
              <div className="pt-5 pb-6 px-5">
                <div className="flex items-center justify-between">
                  <div>
                    <span className="h-8 w-auto">LOGO</span>
                  </div>
                  <div className="-mr-2">
                    <button
                      onClick={toggleMenu}
                      className="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500"
                    >
                      X
                    </button>
                  </div>
                </div>
                <div className="mt-6">
                  <nav className="grid gap-y-8">
                    <a href="#" className="p-3 flex items-center rounded-md hover:bg-gray-50">
                      About
                    </a>
                  </nav>
                </div>
              </div>
            </div>
          </div>
        )}
      </header>
  );
};
Run Code Online (Sandbox Code Playgroud)

您可能还需要处理路线更改时菜单的关闭。

import { useRouter } from "next/router";
import { useEffect, useState } from "react";

const Navbar = () => {
  const [isOpen, setOpen] = useState(false);
  const toggleMenu = () => setOpen(!isOpen);
  const router = useRouter();

  useEffect(() => {
    const closeMenu = () => isOpen && setOpen(false);
    router.events.on("routeChangeStart", closeMenu);
    return () => {
      router.events.off("routeChangeStart", closeMenu);
    };
  }, [isOpen, router]);

  return (
   ...see above example

Run Code Online (Sandbox Code Playgroud)