React使用react-power-tooltip实现点击外部关闭提示框的方案问询
问题根源
你当前的实现存在两个核心问题:
- App.js中
onClose回调调用setShowTooltip时没有传入false值,会导致状态变为undefined,逻辑异常。 - 用
onBlur实现的关闭逻辑,在点击按钮时会先触发tooltip的失焦事件执行关闭,紧接着按钮的点击事件又会执行状态取反,相当于最终状态又变回true,看起来就像按钮关闭功能失效了,而且blur方案本身有局限性,按tab切换焦点也会误触发关闭。
正确实现方案
1. 修正App.js代码
补充按钮ref用于后续点击区域判断,修正onClose的传参逻辑:
import "./styles.css"; import MoreHorizIcon from "@material-ui/icons/MoreHoriz"; import TooltipList from "./TooltipList"; import { useState, useRef } from "react"; export default function App() { const [showTooltip, setShowTooltip] = useState(true); const triggerBtnRef = useRef(null); return ( <div className="App"> <button ref={triggerBtnRef} className="post-section__body__list__item__right__menu-btn" onClick={() => { setShowTooltip((x) => !x); }} style={{ position: "relative" }} > <MoreHorizIcon /> <TooltipList show={showTooltip} triggerRef={triggerBtnRef} onClose={() => { setShowTooltip(false); }} /> </button> </div> ); }
2. 重写TooltipList.js关闭逻辑
用全局点击事件判断点击区域,替换原有的blur方案:
import React, { useEffect, useRef } from "react"; import Tooltip from "react-power-tooltip"; const options = [ { id: "edit", label: "编辑" }, { id: "view", label: "查看" } ]; // 注意你原代码里组件名拼写错误写为了Tooptip,此处修正为正确命名 function TooltipList(props) { const { show, onClose, triggerRef } = props; const tooltipContainerRef = useRef(); useEffect(() => { if (!show) return; const handleClickOutside = (e) => { // 点击区域是触发按钮或者tooltip内部时不关闭 if ( triggerRef.current?.contains(e.target) || tooltipContainerRef.current?.contains(e.target) ) return; onClose(); }; document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, [show, onClose, triggerRef]); return ( <div style={{ display: "inline-flex" }} ref={tooltipContainerRef} > <Tooltip show={show} position="top center" arrowAlign="end" textBoxWidth="180px" fontSize="0.875rem" fontWeight="400" padding="0.5rem 1rem" > {options.map((option) => { return ( <div className="tooltop__option d-flex align-items-center w-100" key={option.id} > {option.icon} <span style={{ fontSize: "1rem" }}>{option.label}</span> </div> ); })} </Tooltip> </div> ); } export default TooltipList;
修改后可实现:
- 点击按钮正常切换tooltip显示/隐藏
- 点击tooltip以外任意区域自动关闭tooltip
- 点击tooltip内部区域不会触发关闭,不影响操作内部选项
内容的提问来源于stack exchange,提问作者CCCC
相关产品推荐
相关产品推荐

