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 进行测试