React-Popper 在挂载时定位不正确

8

我在React中构建了一个自定义的树形视图,每个项都包含一个下拉菜单,使用Popper进行定位。由于子元素在渲染时不可见,因此Popper无法正确地定位下拉菜单,例如:

输入图片描述

当树在挂载时处于打开状态(即子项可见)时,定位是正确的:

输入图片描述

树中的每个级别都通过组件呈现,其基本上看起来像这样:

<div className={ className.join(' ') }>
    <div className={ `collection-nav_item-link depth${depth}` } style={{ paddingLeft: `${paddingLeft}px`}}>
        <Link to={ linkTo } onClick={() => { setIsOpen(!isOpen) }}>
            <i className="collection-nav_item-link_icon"></i>
            <span className="collection-nav_item-link_text">{ category.name }</span>
        </Link>

        <Dropdown
            toggleClassName="btn-icon-white btn-sm"
            toggleContent={ <Icon name="ellipsis-h" />}
            position="bottom-end"
            size="small"
            items={[ 
                { text: 'Edit category' },
                { text: 'Add subcategory', onClick: (() => { dispatch(openAddSubcategory(category)) }) }
            ]} />
    </div>
    { children }
</div>
<代码>Dropdown组件是使用Popper的地方,而且在其他地方都运行良好。在React中,<代码>CategoryNavItem的可见性是通过组件状态来处理的。
有没有办法以编程方式在React中触发Popper的<代码>update()方法?我们应该在切换项目的可见性时强制执行<代码>update。
2个回答

18

事实证明我们只需要从usePopper hook暴露update属性,然后在设置下拉菜单的可见性时调用它即可,例如:

const { styles, attributes, update } = usePopper(referenceElement, popperElement, {
    placement: placement,
    modifiers: [
        { name: 'arrow', options: { element: arrowElement } },
        { name: 'offset', options: { offset: [ 0, 3 ] } }
    ]
});

同样地:

const toggleDropdown = (e) => {
    e.preventDefault();
    e.stopPropagation();

    setVisible(!visible);
    update();
};

这对我帮助很大;在库的钩子文档中,关于如何使用update并不是很清楚。谢谢。 - user1189352
更新函数是异步的,因此您需要在异步函数中使用await update() - Nathan

3
根据文档,您可以手动更新正确的实例以重新计算工具提示位置:
手动更新
您可以通过运行instance.update()来要求Popper重新计算工具提示的位置。
此方法将返回一个Promise,该Promise将使用更新后的State解决,您可以从中选择读取更新后的位置。
const state = await popperInstance.update();
当单击项目可见性切换时,您可以添加您的popper手动更新,就像上面的代码行一样。
这是参考资料

是的,这适用于通常的JS实现,但在React中我们无法访问popperInstance,因为它是通过Popper提供程序处理的。 - BenM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接