首页 > 解决方案 > 反应材质UI在 react-beautiful-dnd Draggable 中拖动时卡住了?

问题描述

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

ListItems有 aListItemText和 a ListItemSecondaryActionwhich 是打开上下文菜单的目标(包装图标)。

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 正在围绕占位符/拖动项目将被放置的位置重新排列。然而,被拖动的项目的上下文菜单图标被冻结在它以前的位置之上,并且其他项目的上下文菜单图标没有移动到新的位置。 一个项目被拖到列表的顶部,并且列表项目被重新排列在它周围,但每个项目的上下文菜单都在它们被拖动之前的相同位置。

只需将 替换为ListItemSecondaryActiona即可div解决问题,但我需要ListItemSecondaryAction.

下面在拖动项目方面按预期工作:IconButton被拖动到 Draggable 中。

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

包含正在拖动的项目的列表。 该项目的上下文菜单图标按预期与项目一起拖动,其他项目上的上下文菜单图标随它们一起移动到列表中的新位置。

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

我如何确保当它在里面时IconButton被拖拽?DraggableListItemSecondaryAction

标签: javascriptreactjsreact-materialreact-beautiful-dnd

解决方案


我在这里使用解决方案的变体修复了图标问题,但不是单独ListItemIcon渲染并仍然渲染ListItemSecondaryAction改变了每个项目的布局的图标问题,我发现ListItemSecondaryAction在拖动时根本不渲染并简单地渲染Icon没有效果更好任何ListItemIconIconButton包装。Icon当渲染为ListItem虽然的孩子时,孤独的人会更暗。在自行设置图标样式以匹配辅助操作中图标的颜色后,它看起来不错。

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 上测试),必须拖动两次才能开始移动项目。我可以将这个更具体的问题放在一个单独的问题中。


推荐阅读