React-beautiful-dnd:如何修复isDraggingOver时列表项下滑问题
react-beautiful-dnd拖拽时列内卡片异常跳动问题
我开发了一个基于react-beautiful-dnd的应用,支持用户在不同列之间拖拽卡片。当将卡片拖入已有卡片的列时,现有卡片会向下跳动。若将卡片拖到列顶部,这种情况合理,但即使拖到列表中间或底部,首项或上方所有卡片仍会下滑。释放鼠标完成拖拽后,卡片会恢复到正确位置,因此问题与isDraggingOver相关。我检查了styled components,发现isDraggingOver仅改变背景色和边框色。
9/6 更新:尝试@Jordan的方案未成功后,我查看项目GitHub Issues找到相关问题。发现不渲染provided.placeholder时问题消失,但控制台会出现未渲染占位符的警告。我尝试用React.cloneElement()包裹它并传入{style: {height: '0'}},但无效。目前只能不渲染占位符,求其他解决办法。
8/25 更新:尝试@Jordan的方案后仍存在问题,以下是我的可拖拽组件TaskCard的代码及对应的Hook代码:
Draggable组件代码
import React, { memo, useState } from 'react' import { Draggable } from 'react-beautiful-dnd' import TaskForm from '../TaskForm/TaskForm' import Task from '../Task/Task' import { useStyletron } from 'baseui' import useDraggableInPortal from '../../Hooks/useDraggableInPortal' const TaskCard = ({ description, id, index, column }) => { const renderDraggable = useDraggableInPortal() const [isEditing, setIsEditing] = useState(false) const [css, theme] = useStyletron() const handleEdit = id => { setIsEditing(true) } return ( <Draggable draggableId={id} index={index}> {renderDraggable((provided, snapshot) => ( <div className={css({ boxSizing: 'border-box', ':focus': { outline: `${theme.colors.hotPink} 3px solid`, borderRadius: '6px', margin: '3px', } })} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}> {!isEditing && <Task column={column} description={description} handleEdit={handleEdit} id={id} snapshot={snapshot} /> } {isEditing && <TaskForm column={column} handleOnCancel={() => setIsEditing(false)} initialValues={{ description, id }} isEditing={true} /> } </div> ))} </Draggable> ) } export default memo(TaskCard)
@Jordan提供的Hook代码
import { createPortal } from 'react-dom' import { useEffect, useRef } from 'react' const useDraggableInPortal = () => { const self = useRef({}).current useEffect(() => { const div = document.createElement('div') div.style.position = 'absolute' div.style.pointerEvents = 'none' div.style.top = '0' div.style.width = '100%' div.style.height = '100%' self.elt = div document.body.appendChild(div) return () => { document.body.removeChild(div) } }, [self]) return (render) => (provided, ...args) => { const element = render(provided, ...args) if (provided.draggableProps.style.position === 'fixed') { return createPortal(element, self.elt) } return element } } export default useDraggableInPortal
恳请各位提供有效的修复方案,谢谢!
内容的提问来源于stack exchange,提问作者Neil Girardi
相关产品推荐
相关产品推荐

