为什么我的 React DND 实现在 Next JS 中不起作用?

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

我有这个 React DND 实现。有多个放置目标。我可以拖动元素,但目标没有接收到它。我尝试在 useDrop 的 drop 函数中执行 console.log 。掉落时控制台中没有任何记录。可能是什么问题?

DND 提供商实施

<DndProvider backend={HTML5Backend} debugMode>
              <TODOSection
                title={"TODOS"}
                todos={normalTodos}
                markCompleted={markCompleted}
                markProgress={markProgress}
              >
                {createTodoFormActive ? (
                  <form
                    className={styles.createTodoForm}
                    onSubmit={handleAddTodoFormSubmit}
                  >
                    <input
                      type="text"
                      className={styles.createTodoInput}
                      placeholder="Enter TODO here..."
                      value={todoInputText}
                      required
                      onChange={(event) => setTodoInputText(event.target.value)}
                    />
                    <button type="submit" className={styles.todoSubmitBtn}>
                      Add
                    </button>
                  </form>
                ) : (
                  <button
                    className={styles.addTodoBtn}
                    onClick={() => setCreateTodoFormActive(true)}
                  >
                    <Icon icon={"carbon:add"} /> Add todos
                  </button>
                )}
              </TODOSection>

              <TODOSection
                title="IN PROGRESS"
                todos={progressTodos}
                markCompleted={markCompleted}
                markProgress={markProgress}
              />
              <TODOSection
                title="COMPLETED"
                todos={completedTodos}
                markCompleted={markCompleted}
                markProgress={markProgress}
              />
            </DndProvider>

使用 useDrag 钩子的可拖动组件

const TODOItem = ({
  children,
  markCompleted,
  markProgress,
  todoId,
}: {
  children: React.ReactNode;
  markCompleted: Function;
  markProgress: Function;
  todoId: string;
}) => {
  const [{ opacity, isDragging, didDrop, dropResult, targetIds }, dragRef] =
    useDrag(() => ({
      type: "todoItem",
      // item: { children },
      item: { id: todoId },
      collect: (monitor) => ({
        opacity: monitor.isDragging() ? 0.5 : 1,
        isDragging: monitor.isDragging(),
        didDrop: monitor.didDrop(),
        dropResult: monitor.getDropResult(),
        targetIds: monitor.getTargetIds(),
      }),
    }));

  const handleDrop = (id: string, monitor: any) => {
    markCompleted(id);
    console.log(monitor);
  };

  console.log(dropResult, targetIds);
  return (
    <div className={styles.todoItem} ref={dragRef} style={{ opacity }}>
      <p className={styles.todoText}>{children}</p>
      <div className={styles.todoActions}>
        <button
          className={`${styles.todoActionBtn} ${styles.markPending}`}
          title="Mark as In Progress"
          onClick={() => markProgress(todoId)}
        >
          <Icon icon={"bx:time-five"} />
        </button>
        <button
          className={`${styles.todoActionBtn} ${styles.markCompleted}`}
          title="Mark as Completed"
          onClick={() => markCompleted(todoId)}
        >
          <Icon icon={"charm:circle-tick"} />
        </button>
      </div>
    </div>
  );
};

删除目标组件

const TODOSection = ({
  todos,
  children,
  markCompleted,
  markProgress,
  title,
}: {
  todos: ITodoItem[];
  children?: React.ReactNode;
  markCompleted: Function;
  markProgress: Function;
  title?: string;
}) => {
  const [{ isOver, canDrop, item }, drop] = useDrop(() => ({
    accept: "todoItem",
    drop: (item) => {
      console.log(item, "dropped");
    },

    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
      item: monitor.getItem(),
    }),
  }));

  console.log(isOver, canDrop, item);

  return (
    <div className={styles.todoSection} ref={drop}>
      <h3 className={styles.todoSectionTitle}>{title}</h3>
      {todos.length > 0 ? (
        todos.map((todo) => (
          <TODOItem
            markCompleted={markCompleted}
            markProgress={markProgress}
            todoId={todo.id}
          >
            {todo.text}
          </TODOItem>
        ))
      ) : (
        <p className={styles.nothingHere}>Nothing here</p>
      )}
      {children}
    </div>
  );
};
javascript reactjs next.js drag-and-drop react-dnd
3个回答
1
投票

React DND 包不起作用。所以,我使用了另一个名为 @dnd-kit

的软件包

实施非常简单,一切都运行良好。如果您正在寻找与 React/Next JS 一起使用的 DND 包,您可以使用它。


1
投票

尝试使用动态导入来导入

DndProvider
HTML5Backend
。为我解决了。

import dynamic from "next/dynamic";
const DndProvider = dynamic(
  () => import("react-dnd").then((dnd) => dnd.DndProvider),
  { ssr: false }
);
const HTML5Backend: any = dynamic(
  () =>
    import('react-dnd-html5-backend').then((html) => html.HTML5Backend as any),
  { ssr: false }
);

0
投票

这是

dragEnd
事件(检查事件对象以获取有关其掉落位置的信息。

或者检查我的开源存储库中的代码: https://github.com/artiphishle/daw

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