useEffect 中的状态未更新
State in useEffect is not updating
我有这个组件,当我点击按钮时它会切换 isMenuActive 的状态,在 useEffect 内部实现该功能时出现问题,当我尝试访问 isMenuActive 内部的值时出现一个奇怪的原因closeTooltip 函数它始终反映 false,即使 isMenuActive 的值已更改为 true。
import { useState, useEffect, useRef } from "react";
import Tooltip from "./Tooltip";
export default function Navbar() {
const [isMenuActive, setIsMenuActive] = useState(false);
const menu = useRef(null);
const handleOnClick = (e) => {
setIsMenuActive((prev) => !prev);
};
useEffect(() => {
const closeTooltip = (e) => {
if (menu.current && !menu.current.contains(e.target)) {
//Here isMenuActive is always false, even after using handleOnClick func
console.log(isMenuActive);
}
};
document.addEventListener("click", closeTooltip, true);
return () => document.removeEventListener("click", closeTooltip, true);
}, [menu]);
return (
<button
className="navbar__notifications"
aria-label="Notificaciones"
name="notification"
onClick={handleOnClick}
ref={menu}
>
{isMenuActive && <Tooltip title="Notificaciones" />}
</button>
);
}
知道为什么会这样吗?
menu
(与 useRef
)总是指同一个对象,因此 useEffect
不会在 menu
的每次更改时触发(即使 menu.current
).
useEffect
只触发3次
- 道具随依赖关系变化
- 状态随依赖关系而变化
- 初始安装的组件
您从 closeTooltip
获得的日志来自初始 useEffect
调用(初始安装的组件)
对于修复,您应该在 useEffect
的依赖列表中添加 isMenuActive
(状态更改)。这将继续收听 isMenuActive
状态变化并相应地更新您的 closeTooltip
事件。
useEffect(() => {
const closeTooltip = (e) => {
if (menu.current && !menu.current.contains(e.target)) {
//Here isMenuActive is always false, even after using handleOnClick func
console.log(isMenuActive);
}
};
document.addEventListener("click", closeTooltip, true);
return () => document.removeEventListener("click", closeTooltip, true);
}, [isMenuActive]);
您可以检查 this sandbox 进行测试
我有这个组件,当我点击按钮时它会切换 isMenuActive 的状态,在 useEffect 内部实现该功能时出现问题,当我尝试访问 isMenuActive 内部的值时出现一个奇怪的原因closeTooltip 函数它始终反映 false,即使 isMenuActive 的值已更改为 true。
import { useState, useEffect, useRef } from "react";
import Tooltip from "./Tooltip";
export default function Navbar() {
const [isMenuActive, setIsMenuActive] = useState(false);
const menu = useRef(null);
const handleOnClick = (e) => {
setIsMenuActive((prev) => !prev);
};
useEffect(() => {
const closeTooltip = (e) => {
if (menu.current && !menu.current.contains(e.target)) {
//Here isMenuActive is always false, even after using handleOnClick func
console.log(isMenuActive);
}
};
document.addEventListener("click", closeTooltip, true);
return () => document.removeEventListener("click", closeTooltip, true);
}, [menu]);
return (
<button
className="navbar__notifications"
aria-label="Notificaciones"
name="notification"
onClick={handleOnClick}
ref={menu}
>
{isMenuActive && <Tooltip title="Notificaciones" />}
</button>
);
}
知道为什么会这样吗?
menu
(与 useRef
)总是指同一个对象,因此 useEffect
不会在 menu
的每次更改时触发(即使 menu.current
).
useEffect
只触发3次
- 道具随依赖关系变化
- 状态随依赖关系而变化
- 初始安装的组件
您从 closeTooltip
获得的日志来自初始 useEffect
调用(初始安装的组件)
对于修复,您应该在 useEffect
的依赖列表中添加 isMenuActive
(状态更改)。这将继续收听 isMenuActive
状态变化并相应地更新您的 closeTooltip
事件。
useEffect(() => {
const closeTooltip = (e) => {
if (menu.current && !menu.current.contains(e.target)) {
//Here isMenuActive is always false, even after using handleOnClick func
console.log(isMenuActive);
}
};
document.addEventListener("click", closeTooltip, true);
return () => document.removeEventListener("click", closeTooltip, true);
}, [isMenuActive]);
您可以检查 this sandbox 进行测试