Javascript 如何创建popper的多个实例?
在我的应用程序中,我尝试使用Popper在应用程序中的每个元素上创建工具提示。 (通常,我只显示一个工具提示,但对于演示文稿,我希望显示多个工具提示) 我写信是为了直接将工具提示附加到ref 它工作得很好,但当我尝试在Javascript 如何创建popper的多个实例?,javascript,reactjs,popper.js,Javascript,Reactjs,Popper.js,在我的应用程序中,我尝试使用Popper在应用程序中的每个元素上创建工具提示。 (通常,我只显示一个工具提示,但对于演示文稿,我希望显示多个工具提示) 我写信是为了直接将工具提示附加到ref 它工作得很好,但当我尝试在[].map()中像常规react组件一样使用它时,我失去了所有的定位: import React,{Component}来自'React'; 从“@bit/bit.base.atoms.ref tooltip”导入{RefTooltip} 导出默认类ExampleUsage扩展
[].map()
中像常规react组件一样使用它时,我失去了所有的定位:
import React,{Component}来自'React';
从“@bit/bit.base.atoms.ref tooltip”导入{RefTooltip}
导出默认类ExampleUsage扩展组件{
状态={ref:[]};
handleRef=(elem)=>{
if(this.state.ref.some(x=>x==elem))返回;
this.setState({ref:[elem]});
}
render(){
返回(
目标
{ /*
* (!)
*This.map()中断工具提示
*
*/ }
{this.state.ref.map((elem,idx)=>(
“工具提示”
))}
);
}
}
//ref-tooltip.tsx
从“React”导入React,{Component};
从“类名称”导入类名称;
//@ts忽略
从“react create ref”导入createRef;
从'@popperjs/core'导入{createPopper,Instance,Options};
从“/ref tooltip.module.scss”导入样式;
导出类型RefTooltipProps={
targetElement?:HTMLElement;
popperOptions?:部分;
}&React.HTMLAttributes;
导出类引用工具提示扩展组件{
private ref=createRef();
私有实例:实例;
组件将卸载(){
这个。销毁();
}
componentDidUpdate(prevProps:RefTooltipProps){
const nextProps=this.props;
如果(prevProps.targetElement!==nextProps.targetElement){
重新定位(nextrops.targetElement);
}
}
私有重新定位=(targetElement?:HTMLElement)=>{
const{popperOptions=popperDefaultOptions}=this.props;
const popperelation=此参考电流;
如果(!targetElement){
这个。销毁();
}
如果(!targetElement | |!PopperRelation)返回;
this.popperInstance=createPopper(targetElement、PopperRelation、PopperProptions);
};
私人销毁(){
如果(!this.popperInstance)返回;
this.popperInstance.destroy();
this.popperInstance=未定义;
}
render(){
const{className,targetElement,…rest}=this.props;
返回(
);
}
}
常量popperDefaultOptions:部分={
位置:'顶部',
修改器:[
{
名称:“flip”,
启用:false,
},
],
};
预期:实际值:
我不明白为什么.map()会破坏popper。至少对于1的数组,它的行为应该相同。
你知道为什么这不起作用吗?请在这里发布相关代码,以供将来参考。
import React, { Component } from 'react';
import { RefTooltip } from '@bit/bit.base.atoms.ref-tooltip'
export default class ExampleUsage extends Component {
state = { ref: [] };
handleRef = (elem) => {
if (this.state.ref.some(x => x === elem)) return;
this.setState({ ref: [elem] });
}
render() {
return (
<div>
<span ref={this.handleRef}>target</span>
{ /*
* (!)
* This .map() breaks tooltip
*
*/ }
{this.state.ref.map((elem, idx) => (
<RefTooltip key={idx} targetElement={elem}>
"tooltip"
</RefTooltip>
))}
</div>
);
}
}
//ref-tooltip.tsx
import React, { Component } from 'react';
import classNames from 'classnames';
//@ts-ignore
import createRef from 'react-create-ref';
import { createPopper, Instance, Options } from '@popperjs/core';
import styles from './ref-tooltip.module.scss';
export type RefTooltipProps = {
targetElement?: HTMLElement;
popperOptions?: Partial<Options>;
} & React.HTMLAttributes<HTMLDivElement>;
export class RefTooltip extends Component<RefTooltipProps> {
private ref = createRef();
private popperInstance?: Instance;
componentWillUnmount() {
this.destroy();
}
componentDidUpdate(prevProps: RefTooltipProps) {
const nextProps = this.props;
if (prevProps.targetElement !== nextProps.targetElement) {
this.reposition(nextProps.targetElement);
}
}
private reposition = (targetElement?: HTMLElement) => {
const { popperOptions = popperDefaultOptions } = this.props;
const popperElement = this.ref.current;
if (!targetElement) {
this.destroy();
}
if (!targetElement || !popperElement) return;
this.popperInstance = createPopper(targetElement, popperElement, popperOptions);
};
private destroy() {
if (!this.popperInstance) return;
this.popperInstance.destroy();
this.popperInstance = undefined;
}
render() {
const { className, targetElement, ...rest } = this.props;
return (
<div
{...rest}
ref={this.ref}
className={classNames(styles.tooltipWrapper, className)}
data-ignore-component-highlight
/>
);
}
}
const popperDefaultOptions: Partial<Options> = {
placement: 'top',
modifiers: [
{
name: 'flip',
enabled: false,
},
],
};