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



我有这个React DND实现。有多个投放目标。我可以拖动元素,但目标无法接收。我试着在useDrop的drop函数中做console.log。drop时控制台没有任何登录内容。问题是什么呢?

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>
);
};

React DND包无法工作。因此,我使用了另一个名为@ ddn -kit

的包实现很容易,一切都工作得很好。如果你正在寻找一个与React/Next JS一起使用的DND包,你可以使用它。

尝试动态导入DndProviderHTML5Backend

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 }
);

相关内容

  • 没有找到相关文章

最新更新