过一会儿在Next.js中隐藏元素

问题描述

我有一个标头组件作为功能组件。单击徽标文本时,我想显示一个弹出窗口。一段时间后,它将自动关闭。我使用挂钩来表示弹出状态。但是设置状态函数在setTimeout函数中不起作用。该如何解决

import Link from 'next/link'
import style from './header.module.css'

const Header = () => {
  const [popupOpen,setPopupOpen] = React.useState(false)

  return (
    <header className={style.header}>
      <nav className={style.nav}>
        <div
          className={style.popupContainer}
          onClick={() => {
            setPopupOpen(!popupOpen)
            console.log(popupOpen)
            setTimeout(() => {
              console.log(popupOpen)
              setPopupOpen(!popupOpen)
              console.log(popupOpen)
            },1000)
          }}
        >
          <span className={style.logo}>logo</span>

          <span
            className={`${style.popupText} ${
              popupOpen ? style.show : style.hide
            }`}
          >
            Popup Text
          </span>
        </div>

        <ul className={style.ul}>
          <li>
            <Link href='/'>
              <a>.home</a>
            </Link>
          </li>
          <li>
            <Link href='/contact'>
              <a>.contact</a>
            </Link>
          </li>
        </ul>
      </nav>
    </header>
  )
}

export default Header

控制台日志:

console log

解决方法

我建议,这是与以下问题相同的问题:

React - useState - why setTimeout function does not have latest state value?

const _onClick = () => {
     setPopupOpen(!popupOpen);

     setTimeout(() => {
         setPopupOpen(popupOpen => !popupOpen)
     },2000);
};
,

之所以发生,是因为setPopupOpen是异步的。因此,到setPopupOpen(!popupOpen)被调用时,它的值与onClick首先setPopupOpen(!popupOpen)相同,因此最终当它调用两个setPopup doing same state update时,即都更新为false。更好的方法是使用setPopupOpen回调函数来更新值。我添加了这段代码。

import { useState } from "react";
import Link from "next/link";
import style from "./style.module.css";

const Header = () => {
  const [popupOpen,setPopupOpen] = useState(false);

  const toggle = () => {
    setPopupOpen((prev) => !prev);
  };
  const onClick = () => {
    setPopupOpen(!popupOpen);
    setTimeout(() => {
      toggle();
    },1000);
  };

  return (
    <header className={style.header}>
      <nav className={style.nav}>
        <div className={style.popupContainer} onClick={onClick}>
          <span className={style.logo}>Logo</span>

          {popupOpen && (
            <span
              className={`${style.popupText} ${
                popupOpen ? style.show : style.hide
              }`}
            >
              Popup Text
            </span>
          )}
        </div>

        <ul className={style.ul}>
          <li>
            <Link href="/">
              <a>.home</a>
            </Link>
          </li>
          <li>
            <Link href="/contact">
              <a>.contact</a>
            </Link>
          </li>
        </ul>
      </nav>
    </header>
  );
};

export default function IndexPage() {
  return (
    <div>
      <Header />
    </div>
  );
}


以下是演示:https://codesandbox.io/s/pedantic-haibt-iqecz?file=/pages/index.js:0-1212