React Beautiful DND 不起作用,元素不可拖动
React Beautiful DND not working, element is not draggable
我一直在尝试使用 react-beautiful-dnd 库在我的卡片中实现我的重新排序列表,但我以与 egghead.io 课程类似的方式尝试了所有内容,但无法使其正常工作。这是我的代码:
import React, { Component } from "react";
import { Card, Badge } from "react-bootstrap";
import "./projects.scss";
import projectInfo1 from "../../jsonData/projects1";
import { IconContext } from "react-icons";
import { FiPlus } from "react-icons/fi";
import { Droppable, DragDropContext, Draggable } from "react-beautiful-dnd";
class Projects extends Component {
constructor(props) {
super(props);
this.state = {};
this.onDragEnd = this.onDragEnd.bind(this);
this.onDragStart = this.onDragStart.bind(this);
}
onDragEnd = result => {};
onDragStart = result => {};
render() {
return (
<div className="projectCards">
{projectInfo1.projectsOrder.map((projectID) => {
const project = projectInfo1.projects[projectID];
return (
<DragDropContext onDragEnd={this.onDragEnd} onDragStart={this.onDragStart}>
<Card className="projectCard" bg="light" style={{ width: "21rem" }} key={project.id}>
<Card.Header color="#366FF0" className="projectcardheader">
{project.projectName}
</Card.Header>
<Droppable droppableId={project.id}>
{(provided) => (
<div
className="cardcontent"
innerRef={provided.innerRef}
{...provided.droppableProps}
>
{project.topics.map((j, index) => {
return (
<Draggable draggableId={j.id} index={index}>
{(provided) => (
<Card
key={j.id}
className="topicscard"
{...provided.draggableProps}
{...provided.dragHandleProps}
innerRef={provided.innerRef}
>
<Card.Title className="topicsheading">
{j.topicName}
</Card.Title>
<Card.Text className="topicdescription">
{j.topicDescription}
</Card.Text>
<div>
{j.topicTags ? (
j.topicTags.map((k) => {
return (
<Badge
variant="primary"
className="tags"
>
{k}
</Badge>
);
})
) : (
<Badge variant="primary"></Badge>
)}
</div>
</Card>
)}
</Draggable>
);
})}
{provided.placeholder}
</div>
)}
</Droppable>
<div className="addnewcard">
<IconContext.Provider
value={{
style: { verticalAlign: "middle" },
className: "reacticon",
}}
>
<FiPlus />
</IconContext.Provider>{" "}
Add another discussion
</div>
</Card>
</DragDropContext>
);
})}
</div>
);
}
}
export default Projects;
另外我附上了一张照片,它只是显示拖动光标悬停在卡片上,但拖动时没有任何反应,任何帮助都会救我!
const projectsInfo1 = {
projectsOrder:['Project-2','Project-1','Project-5','Project-4','Project-3'],
projects: {
'Project-1':{
projectName: "Project 1",
id:"p1",
topics:[{
id:"p1t1",
topicName: "Adding a feature: GSoC1",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",
topicTags:['ReactJs','NodeJS']
},
{ id:'p1t2',
topicName: "Adding a feature: GSoC2",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",
topicTags:['ReactJs','NodeJS']
},
{ id:'p1t3',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",
topicTags:['ReactJs','NodeJS']
},
{ id: 'p1t4',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",
topicTags:['ReactJs','NodeJS']
}],
},
'Project-2':{
projectName: "Project 2",
id:'p2',
topics:[{
id:'p2t1',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p2t2',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p2t3',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p2t4',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
}],
},
'Project-3':{
projectName: "Project 3",
id:'p3',
topics:[{
id:'p3t1',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p3t2',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p3t3',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p3t4',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
}],
},
'Project-4':{
projectName: "Project 4",
id:'p4',
topics:[{
id:'p4t1',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p4t2',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p4t3',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p4t4',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
}],
},
'Project-5':{
projectName: "Project 5",
id:'p5',
topics:[{
id:'p5t1',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p5t2',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p5t3',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p5t4',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
}],
},
},
};
export default projectsInfo1;
NOTE :
After the conversation in comment , issue was with innerRef
<div innerRef={provided.innerRef}
to <div ref={provided.innerRef}
In demo they were using styled component so they are using innerRef
, but if you are using simple div then you should use just ref
问题:
1)不会自动运行,需要在拖拽结束事件上写代码onDragEnd
2) 没有状态管理,所以即使你对导入的 json 进行更改,也不会反映为 react 不知道重新再次渲染 dom。
解法:
1) 在 state
中维护导入的数据
2) 在 onDragEnd
中写一些代码,检查那里的所有条件并相应地对你的状态应用更改(不要改变状态,否则它会不反映变化)
Note : Below is just code snippet of demo from egghead.io for sorting
listing within same droppable area , just give overall idea how it
should be
onDragEnd = result => {
const { destination, source, draggableId } = result
if (!destination) {
return
}
if (
destination.droppableId === source.droppableId &&
destination.index === source.index
) {
return
}
const start = this.state.columns[source.droppableId]
const finish = this.state.columns[destination.droppableId]
// this is the logic behind sorting state , you have to do it by your self
if (start === finish) {
const newTaskIds = Array.from(start.taskIds)
newTaskIds.splice(source.index, 1)
newTaskIds.splice(destination.index, 0, draggableId)
const newColumn = {
...start,
taskIds: newTaskIds
}
const newState = {
...this.state,
columns: {
...this.state.columns,
[newColumn.id]: newColumn
}
}
this.setState(newState)
return
}
}
工作演示:
我一直在尝试使用 react-beautiful-dnd 库在我的卡片中实现我的重新排序列表,但我以与 egghead.io 课程类似的方式尝试了所有内容,但无法使其正常工作。这是我的代码:
import React, { Component } from "react";
import { Card, Badge } from "react-bootstrap";
import "./projects.scss";
import projectInfo1 from "../../jsonData/projects1";
import { IconContext } from "react-icons";
import { FiPlus } from "react-icons/fi";
import { Droppable, DragDropContext, Draggable } from "react-beautiful-dnd";
class Projects extends Component {
constructor(props) {
super(props);
this.state = {};
this.onDragEnd = this.onDragEnd.bind(this);
this.onDragStart = this.onDragStart.bind(this);
}
onDragEnd = result => {};
onDragStart = result => {};
render() {
return (
<div className="projectCards">
{projectInfo1.projectsOrder.map((projectID) => {
const project = projectInfo1.projects[projectID];
return (
<DragDropContext onDragEnd={this.onDragEnd} onDragStart={this.onDragStart}>
<Card className="projectCard" bg="light" style={{ width: "21rem" }} key={project.id}>
<Card.Header color="#366FF0" className="projectcardheader">
{project.projectName}
</Card.Header>
<Droppable droppableId={project.id}>
{(provided) => (
<div
className="cardcontent"
innerRef={provided.innerRef}
{...provided.droppableProps}
>
{project.topics.map((j, index) => {
return (
<Draggable draggableId={j.id} index={index}>
{(provided) => (
<Card
key={j.id}
className="topicscard"
{...provided.draggableProps}
{...provided.dragHandleProps}
innerRef={provided.innerRef}
>
<Card.Title className="topicsheading">
{j.topicName}
</Card.Title>
<Card.Text className="topicdescription">
{j.topicDescription}
</Card.Text>
<div>
{j.topicTags ? (
j.topicTags.map((k) => {
return (
<Badge
variant="primary"
className="tags"
>
{k}
</Badge>
);
})
) : (
<Badge variant="primary"></Badge>
)}
</div>
</Card>
)}
</Draggable>
);
})}
{provided.placeholder}
</div>
)}
</Droppable>
<div className="addnewcard">
<IconContext.Provider
value={{
style: { verticalAlign: "middle" },
className: "reacticon",
}}
>
<FiPlus />
</IconContext.Provider>{" "}
Add another discussion
</div>
</Card>
</DragDropContext>
);
})}
</div>
);
}
}
export default Projects;
另外我附上了一张照片,它只是显示拖动光标悬停在卡片上,但拖动时没有任何反应,任何帮助都会救我!
const projectsInfo1 = {
projectsOrder:['Project-2','Project-1','Project-5','Project-4','Project-3'],
projects: {
'Project-1':{
projectName: "Project 1",
id:"p1",
topics:[{
id:"p1t1",
topicName: "Adding a feature: GSoC1",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",
topicTags:['ReactJs','NodeJS']
},
{ id:'p1t2',
topicName: "Adding a feature: GSoC2",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",
topicTags:['ReactJs','NodeJS']
},
{ id:'p1t3',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",
topicTags:['ReactJs','NodeJS']
},
{ id: 'p1t4',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",
topicTags:['ReactJs','NodeJS']
}],
},
'Project-2':{
projectName: "Project 2",
id:'p2',
topics:[{
id:'p2t1',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p2t2',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p2t3',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p2t4',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
}],
},
'Project-3':{
projectName: "Project 3",
id:'p3',
topics:[{
id:'p3t1',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p3t2',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p3t3',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p3t4',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
}],
},
'Project-4':{
projectName: "Project 4",
id:'p4',
topics:[{
id:'p4t1',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p4t2',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p4t3',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p4t4',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
}],
},
'Project-5':{
projectName: "Project 5",
id:'p5',
topics:[{
id:'p5t1',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p5t2',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p5t3',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
},
{ id:'p5t4',
topicName: "Adding a feature: GSoC",
topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."
}],
},
},
};
export default projectsInfo1;
NOTE :
After the conversation in comment , issue was with
innerRef
<div innerRef={provided.innerRef}
to<div ref={provided.innerRef}
In demo they were using styled component so they are using
innerRef
, but if you are using simple div then you should use justref
问题:
1)不会自动运行,需要在拖拽结束事件上写代码onDragEnd
2) 没有状态管理,所以即使你对导入的 json 进行更改,也不会反映为 react 不知道重新再次渲染 dom。
解法:
1) 在 state
2) 在 onDragEnd
中写一些代码,检查那里的所有条件并相应地对你的状态应用更改(不要改变状态,否则它会不反映变化)
Note : Below is just code snippet of demo from egghead.io for sorting listing within same droppable area , just give overall idea how it should be
onDragEnd = result => {
const { destination, source, draggableId } = result
if (!destination) {
return
}
if (
destination.droppableId === source.droppableId &&
destination.index === source.index
) {
return
}
const start = this.state.columns[source.droppableId]
const finish = this.state.columns[destination.droppableId]
// this is the logic behind sorting state , you have to do it by your self
if (start === finish) {
const newTaskIds = Array.from(start.taskIds)
newTaskIds.splice(source.index, 1)
newTaskIds.splice(destination.index, 0, draggableId)
const newColumn = {
...start,
taskIds: newTaskIds
}
const newState = {
...this.state,
columns: {
...this.state.columns,
[newColumn.id]: newColumn
}
}
this.setState(newState)
return
}
}
工作演示: