我正在使用 React-Bootstrap Popover,我想知道是否有任何内置属性可以添加到 Popover 本身或 OverlayTrigger,这样一次只会显示一个弹出窗口。
您可以尝试
rootClose
道具,当用户在叠加层外单击时将触发 onHide
。请注意,在这种情况下,onHide
是强制性的。例如:
const Example = React.createClass({
getInitialState() {
return { show: true };
},
toggle() {
this.setState({ show: !this.state.show });
},
render() {
return (
<div style={{ height: 100, position: 'relative' }}>
<Button ref="target" onClick={this.toggle}>
I am an Overlay target
</Button>
<Overlay
show={this.state.show}
onHide={() => this.setState({ show: false })}
placement="right"
container={this}
target={() => ReactDOM.findDOMNode(this.refs.target)}
rootClose
>
<CustomPopover />
</Overlay>
</div>
);
},
});
我设法以一种有点非常规的方式做到了这一点。您可以创建一个类来跟踪所有工具提示的处理程序:
export class ToolTipController {
showHandlers = [];
addShowHandler = (handler) => {
this.showHandlers.push(handler);
};
setShowHandlerTrue = (handler) => {
this.showHandlers.forEach((showHandler) => {
if (showHandler !== handler) {
showHandler(false);
}
});
handler(true);
};
}
然后在您的工具提示组件中:
const CustomToolTip = ({
children,
controller,
}: CustomToolTipProps) => {
const [showTip, setShowTip] = useState(false);
useEffect(() => {
if (!controller) return;
controller.addShowHandler(setShowTip);
}, []);
return (
<OverlayTrigger
onToggle={(nextShow) => {
if (!nextShow) return setShowTip(false);
controller ? controller.setShowHandlerTrue(setShowTip) : setShowTip(true);
}}
show={showTip}
overlay={(props: any) => <Overlay {...props}/>}
>
<div className={containerClassName}>{children}</div>
</OverlayTrigger>
);
};
这不是一个真正的“Reacty”解决方案,但它工作得很好。请注意,控制器在这里是完全可选的,因此如果您想要,您不能将其传入,然后它的行为就像一个普通的弹出窗口,一次允许多个工具提示。
基本上要使用它,您可以创建另一个组件并实例化一个您传递给 CustomToolTip 的控制器。然后对于使用该组件呈现的任何工具提示,一次只会出现 1 个。
STEP 1:我们声明一个包含当前 popover id 的 currentPopover 变量,因此我们确定一次只有一个 popover。
const [currentPopover, setCurrentPopover] = useState(null);
第 2 步:来自 react-bootstrap 的 OverlayTrigger 具有手动设置弹出状态的属性。如果 currentPopover 变量等于 popover id 那么我们显示 popover.
show={currentPopover === `${i}`}
第 3 步:来自 react-bootstrap 的 OverlayTrigger 具有手动处理弹出窗口点击的属性。单击时,我们使用新 id 更新 currentPopover 变量,除非我们单击当前。
onToggle={() => {
if( currentPopover === `${i}` )
setCurrentPopover(null)
else
setCurrentPopover(`${i}`)
}}
结果:
const [currentPopover, setCurrentPopover] = useState(null);
<OverlayTrigger
trigger="click"
show={currentPopover == `${i}`}
onToggle={() => {
if( currentPopover == `${i}` )
setCurrentPopover(null)
else
setCurrentPopover(`${i}`)
}}
>
(我使用
${i}
作为 id,因为我的 OverlayTrigger 在一个循环中,其中 i 是索引)
我知道这是一个老问题,但是对于这里有同样问题的人,这种方法对你有用:
<Overlay
...
onHide={() => this.setState({ show: false })}
rootClose={true}
rootCloseEvent="mousedown"
>