react-beautiful-dnd 在看板的初始渲染中不起作用

问题描述 投票:0回答:1

我已成功将看板添加到我的 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>
      )}
    </>
  )
}


javascript reactjs next.js drag-and-drop react-beautiful-dnd
1个回答
0
投票

正如我在上面的屏幕截图中显示的警告,板 ID 是数字,因此您必须在 droppableId 和 DraggleId 属性中将其替换为 uuid(长唯一字符串:“ashkdjka-3unbsdb-asnj”)

© www.soinside.com 2019 - 2024. All rights reserved.