【问题标题】:React MaterialUI <ListItemSecondaryAction> gets stuck when dragging inside react-beautiful-dnd Draggable?React MaterialUI <ListItemSecondaryAction> 在 react-beautiful-dnd Draggable 中拖动时卡住了?
【发布时间】:2021-07-02 19:14:18
【问题描述】:

我正在使用react-beautiful-dnd 制作一些使用Material UI ListItems 的可拖动列表项。

我的ListItems 有一个ListItemText 和一个ListItemSecondaryAction,这是一个用于打开上下文菜单的目标(包含一个图标)。

const DraggableListItem = ({ leaf, index, path, handleClick }) => {

    return (
        <Draggable draggableId={String(leaf.id)} index={index}>
            {(provided) => (
                <ListItem 
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                    innerRef={provided.innerRef}
                    button component={NavLink}
                    to={path + '/' + leaf.id}
                >
                    <ListItemText primary={leaf.content} />
                    <ListItemSecondaryAction>
                        <IconButton edge="end" aria-label="more options" value={JSON.stringify(leaf)} onClick={handleClick}>
                            <MoreHorizIcon />
                        </IconButton>
                    </ListItemSecondaryAction>
                </ListItem>
            )}
        </Draggable>
    )
}

我面临的问题是,当拖动 Draggable 时,ListItemSecondaryAction 内的上下文菜单图标会向上移动一点然后冻结,尽管 ListItemText 按预期被拖动。

您可以在下面看到项目被拖到列表顶部,而其他ListItemTexts 正在围绕占位符/拖放项目重新排列。然而,被拖动的项目的上下文菜单图标被冻结在它以前的位置之上,并且其他项目的上下文菜单图标没有移动到新的位置。

只需将ListItemSecondaryAction 替换为div 即可解决问题,但我需要ListItemSecondaryAction 提供的目标。

在拖动项目方面,以下内容按预期工作:IconButton 被拖动到 Draggable 内。

<div>
    <IconButton>
        <MoreHorizIcon />
    </IconButton>
</div>

我尝试只在不拖动时渲染ListItemSecondaryAction(而不是在拖动时渲染div),但是仍然存在延迟,其中被拖动项目的上下文菜单显示卡在一个位置短暂的一段时间。我也可以在拖动时根本不渲染上下文菜单的目标 + 图标,但是会发生同样难看的图标卡在奇怪的地方一秒钟的问题。

当IconButton在ListItemSecondaryAction内部时,如何确保Draggable与Draggable一起被拖动?

【问题讨论】:

    标签: javascript reactjs react-material react-beautiful-dnd


    【解决方案1】:

    我使用解决方案here 的变体修复了图标问题,但不是渲染单独的ListItemIcon 并仍然渲染ListItemSecondaryAction,这改变了每个项目的布局,我发现最好不要拖动时完全渲染 ListItemSecondaryAction 并简单地渲染 Icon 而没有任何 ListItemIcon 或 IconButton 包装器。不过,当呈现为 ListItem 的子代时,单独的 Icon 会更暗。在自行设置图标样式以匹配辅助操作中图标的颜色后,它看起来不错。

    dragInProgress 是从父列表传递给所有列表项的状态,以便它们在拖动时仅呈现图标。 snapshot 来自Draggable 中函数传递的快照,如链接问题所示。还检查了snapshot.isDragging 以避免在状态dragInProgress 更新并导致项目重新渲染时被拖动项目的图标瞬间跳转。

    <ListItem 
        {...provided.draggableProps}
        {...provided.dragHandleProps}
        ref={provided.innerRef} 
    >
        <ListItemText primary={item.content} />
        {dragInProgress || snapshot.isDragging ?
            <MoreHorizIcon style={{color:'rgba(0, 0, 0, 0.54)'}} />
            :
            <ListItemSecondaryAction>
                <IconButton>
                    <MoreHorizIcon />
                </IconButton>
            </ListItemSecondaryAction>
        }
    </ListItem>
    

    注意: 不幸的是,不拖动时呈现的ListItemSecondaryAction 在触摸时效果不佳(在 chrome 上的 android 上测试),必须拖动两次才能开始移动项目。我可以将这个更具体的问题放在一个单独的问题中。

    【讨论】:

    • 您能解释一下您的状态“dragInProgress”是如何计算的吗?我在此文档中找不到任何内容。
    • 嘿@JoeMethven,它在 的 onDragStart 中设置为 true,在 onDragEnd 中设置为 false。
    猜你喜欢
    • 2019-06-06
    • 2022-08-24
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 2019-04-29
    • 2019-03-19
    • 2020-08-04
    相关资源
    最近更新 更多