我已经成功地将看板板添加到我的Next.js和TypeScript项目中。然而,我在初始渲染过程中遇到了一个小问题,当我刷新页面时,拖放功能不起作用,但当我删除代码的<div key={board.id}>
部分并保存文件时,或者将其还原并保存文件时,拖放功能开始完美地工作。
我怀疑这个问题与最初的渲染有关。
提前感谢您的任何帮助!
控制台错误:
下面是完整的代码:
import { useEffect, useState } from 'react'
import {
DragDropContext,
Draggable,
DropResult,
Droppable
} from 'react-beautiful-dnd'
import { BsArrowRight, BsPlus, BsThreeDotsVertical } from 'react-icons/bs'
import RadialProgrss from '../RadialProgress'
interface Candidate {
id: number | string
priority: number
title: string
description?: string
}
interface Board {
id: number | string
name: string
items: Candidate[]
}
function createGuidId(): string {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0
const v = c === 'x' ? r : (r & 0x3) | 0x8
return v.toString(16)
})
}
const initialData: Board[] = [
{
id: '1000',
name: 'Candidates',
items: [
{
id: '1',
priority: 0,
title: 'Amin Azimi',
description:
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime mollitia,'
},
{
id: '2',
priority: 1,
title: 'Max Vokshoor',
description:
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime mollitia,'
}
]
},
{
id: '1001',
name: 'Invite to interview',
items: [
{
id: '3',
priority: 2,
title: 'John Walsh',
description:
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime mollitia,'
}
]
}
]
export default function Kanban() {
const [boardData, setBoardData] = useState<Board[]>(initialData)
const [showForm, setShowForm] = useState(false)
const [ready, setReady] = useState(false)
const [selectedBoard, setSelectedBoard] = useState(0)
useEffect(() => {
if (typeof window !== undefined) {
setReady(true)
setBoardData(initialData)
}
}, [])
const onDragEnd = (result: DropResult) => {
if (!result.destination) return
let newBoardData = boardData
var dragItem =
newBoardData[parseInt(result.source.droppableId)].items[
result.source.index
]
newBoardData[parseInt(result.source.droppableId)].items.splice(
result.source.index,
1
)
newBoardData[parseInt(result.destination.droppableId)].items.splice(
result.destination.index,
0,
dragItem
)
setBoardData(newBoardData)
}
const onTextAreaKeyPress = (e: any) => {
if (e.keyCode === 13) {
//Enter
const val = e.target.value
if (val.length === 0) {
setShowForm(false)
} else {
const boardId = e.target.attributes['data-id']!.value
const item: Candidate = {
id: createGuidId(),
title: val,
priority: 0,
description:
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime mollitia,'
}
let newBoardData = [...boardData]
newBoardData[boardId].items.push(item)
setBoardData(newBoardData)
setShowForm(false)
e.target.value = ''
}
}
}
return (
<>
{ready && (
<div className="h-screen w-full">
<DragDropContext onDragEnd={onDragEnd}>
<div className="grid grid-cols-4 gap-5">
{boardData?.map((board, bIndex) => {
return (
<div key={board.id}>
<Droppable droppableId={bIndex.toString()}>
{(provided, snapshot) => (
<div
{...provided.droppableProps}
ref={provided.innerRef}
>
<div
className={`relative flex flex-col overflow-hidden rounded-md bg-gray-100 ${
snapshot.isDraggingOver ? 'bg-gray-200' : ''
}`}
>
<div className="mb-3 p-3">
<h4 className="flex items-center justify-between rounded-[8px] bg-white p-3">
<span className="text-[18px] text-gray-600">
{board.name}
</span>
<BsThreeDotsVertical className="h-5 w-5 text-gray-500" />
</h4>
</div>
<div
className="h-auto overflow-y-auto overflow-x-hidden"
style={{ maxHeight: 'calc(100vh - 290px)' }}
>
{board?.items?.length > 0 &&
board?.items?.map(
(item: Candidate, iIndex: number) => {
return (
<Draggable
index={iIndex}
draggableId={item.id.toString()}
key={item.id}
>
{iProvided => (
<div
ref={iProvided.innerRef}
{...iProvided.draggableProps}
{...iProvided.dragHandleProps}
className="m-3 mt-0 rounded-md bg-white p-3 last:mb-0"
>
<h4
className="mb-6 flex items-center justify-between
rounded-[8px] bg-white "
>
<span className="text-[18px] text-gray-600">
{item.title}
</span>
<BsThreeDotsVertical className="h-5 w-5 text-gray-500" />
</h4>
<p className="mb-6 text-[14px] text-gray-600">
{item?.description}
</p>
<div className="flex justify-between">
<div className="flex items-center gap-2">
<RadialProgrss percent={75} />
<p className="text-[14px]">
2 Comments
</p>
</div>
<p className="text-[14px flex items-center gap-2 text-secondary-second-70">
Read more <BsArrowRight />
</p>
</div>
</div>
)}
</Draggable>
)
}
)}
{provided.placeholder}
</div>
{showForm && selectedBoard === bIndex ? (
<div className="p-3">
<textarea
className="w-full rounded border-gray-300 p-3 focus:ring-purple-400"
rows={3}
placeholder="Some info"
data-id={bIndex}
onKeyDown={e => onTextAreaKeyPress(e)}
/>
</div>
) : (
<button
className="my-3 flex items-center justify-center space-x-2 text-lg"
onClick={() => {
setSelectedBoard(bIndex)
setShowForm(true)
}}
>
<span>Add New</span>
<BsPlus className="h-5 w-5 text-gray-500" />
</button>
)}
</div>
</div>
)}
</Droppable>
</div>
)
})}
</div>
</DragDropContext>
</div>
)}
</>
)
}
1条答案
按热度按时间f45qwnt81#
正如我在上面的屏幕截图中显示的警告,板id是number,所以你必须用uuid(long-unique-string:“ashkdjka-3unbsdb-asnj”)在dropableId和draggleId prop 中