问题描述
我有一个标头组件作为功能组件。单击徽标文本时,我想显示一个弹出窗口。一段时间后,它将自动关闭。我使用挂钩来表示弹出状态。但是设置状态函数在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
控制台日志:
解决方法
我建议,这是与以下问题相同的问题:
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