- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在将此代码实现到我的图像 uploader 之前,我正在开发一个简单版本的 ReactDND。
每次添加图像时,它都会被添加到状态并传递到 ReactDND,以便它可以拖动和放置(以便用户可以重新排列图像)。
一切都很好,除了一件事。我遇到的问题是添加多个图像后,一旦我拖放图像(有效),ReactDND 的状态就不再更新,并且我无法添加新图像。
下面是我的代码(请注意,我只是使用按钮添加额外的项目来说明):
主要组件:
import React from 'react';
// Drag and drop stuff
import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import Container from './Container';
class ImageUploader extends React.Component {
constructor(props) {
super(props);
this.state = {
list: [],
listCount: 1
};
this.onAddItem = this.onAddItem.bind(this);
}
onAddItem(e) {
e.preventDefault();
var listArray = this.state.list;
var buildObject = {
text: 'Jeremy' + this.state.listCount.toString(),
age: '25',
id: this.state.listCount
};
listArray.push(buildObject);
let newListCount = this.state.listCount + 1;
this.setState({
list: listArray,
listCount: newListCount
});
console.log(this.state.list);
}
render() {
return (
<div>
<h1>Add to List</h1>
<button onClick={this.onAddItem}>Add Item</button>
<h1>The List</h1>
<Container id={1} list={this.state.list} />
</div>
)
}
}
export default DragDropContext(HTML5Backend)(ImageUploader);
容器:
import React, { Component } from 'react';
import update from 'react/lib/update';
import Card from './Card';
import { DropTarget } from 'react-dnd';
class Container extends Component {
constructor(props) {
super(props);
this.state = { cards: props.list };
}
pushCard(card) {
this.setState(update(this.state, {
cards: {
$push: [ card ]
}
}));
}
removeCard(index) {
this.setState(update(this.state, {
cards: {
$splice: [
[index, 1]
]
}
}));
}
moveCard(dragIndex, hoverIndex) {
const { cards } = this.state;
const dragCard = cards[dragIndex];
this.setState(update(this.state, {
cards: {
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragCard]
]
}
}));
}
render() {
const { cards } = this.state;
const { canDrop, isOver, connectDropTarget } = this.props;
const isActive = canDrop && isOver;
const style = {
width: "200px",
height: "404px",
border: '1px dashed gray'
};
const backgroundColor = isActive ? 'lightgreen' : '#FFF';
return connectDropTarget(
<div className="houzes-dropbox">
{cards.map((card, i) => {
return (
<Card
key={card.id}
index={i}
listId={this.props.id}
card={card}
removeCard={this.removeCard.bind(this)}
moveCard={this.moveCard.bind(this)} />
);
})}
</div>
);
}
}
const cardTarget = {
drop(props, monitor, component ) {
const { id } = props;
const sourceObj = monitor.getItem();
if ( id !== sourceObj.listId ) component.pushCard(sourceObj.card);
return {
listId: id
};
}
}
export default DropTarget("CARD", cardTarget, (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
canDrop: monitor.canDrop()
}))(Container);
卡片:
import React, { Component } from 'react';
import { findDOMNode } from 'react-dom';
import { DragSource, DropTarget } from 'react-dnd';
import flow from 'lodash/flow';
const style = {
border: '1px dashed grey',
padding: '0.5rem 1rem',
margin: '.5rem',
backgroundColor: 'white',
cursor: 'move'
};
class Card extends Component {
render() {
const { card, isDragging, connectDragSource, connectDropTarget } = this.props;
const opacity = isDragging ? 0 : 1;
// Background URL
let backgroundUrl = {
backgroundImage: "url(" + "http://localhost:4000/uploads/2017/8/a3ff91dc-2f80-42f7-951a-e9a74bf954d7-1200x800.jpeg" + ")"
};
console.log(card);
return connectDragSource(connectDropTarget(
<div className={`uploadedImageWrapper col-md-6 col-sm-12`}>
<div className="uploadedImage">
<span style={backgroundUrl} />
{card.text}
{card.age}
</div>
</div>
));
}
}
const cardSource = {
beginDrag(props) {
return {
index: props.index,
listId: props.listId,
card: props.card
};
},
endDrag(props, monitor) {
const item = monitor.getItem();
const dropResult = monitor.getDropResult();
if ( dropResult && dropResult.listId !== item.listId ) {
props.removeCard(item.index);
}
}
};
const cardTarget = {
hover(props, monitor, component) {
const dragIndex = monitor.getItem().index;
const hoverIndex = props.index;
const sourceListId = monitor.getItem().listId;
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
// Determine rectangle on screen
const hoverBoundingRect = findDOMNode(component).getBoundingClientRect();
// Get vertical middle
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
// Determine mouse position
const clientOffset = monitor.getClientOffset();
// Get pixels to the top
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
// Only perform the move when the mouse has crossed half of the items height
// When dragging downwards, only move when the cursor is below 50%
// When dragging upwards, only move when the cursor is above 50%
// Dragging downwards
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
return;
}
// Dragging upwards
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return;
}
// Time to actually perform the action
if ( props.listId === sourceListId ) {
props.moveCard(dragIndex, hoverIndex);
// Note: we're mutating the monitor item here!
// Generally it's better to avoid mutations,
// but it's good here for the sake of performance
// to avoid expensive index searches.
monitor.getItem().index = hoverIndex;
}
}
};
export default flow(
DropTarget("CARD", cardTarget, connect => ({
connectDropTarget: connect.dropTarget()
})),
DragSource("CARD", cardSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
}))
)(Card);
回顾一下,我可以将项目添加到状态中,并且它们变得可拖动和可放置。但是拖放元素后,我无法再向状态添加更多项目。
关于解决方案有什么想法吗?我做错了什么?
感谢您浏览此内容以及任何答案。干杯。
最佳答案
@臭名昭著。
我已经检查了您的代码并解决了问题。当您拖放一个元素时,会更改 Container 的状态,但不会更改 ImageUploader 的状态。
所以我做了一个函数来通知Container的状态已经改变。此外,我将 componentWillReceiveProps() 函数插入到 Container 中,并更新了该函数中 Container 的状态。
问题终于解决了。
这是更改后的代码。
主要组件:
import React from 'react';
// Drag and drop stuff
import {DragDropContext} from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import Container from './Container';
class ImageUploader extends React.Component {
constructor(props) {
super(props);
this.state = {
list: [],
listCount: 1
};
this.onAddItem = this
.onAddItem
.bind(this);
this.listChanged = this.listChanged.bind(this);
}
onAddItem(e) {
e.preventDefault();
var listArray = this.state.list;
var buildObject = {
text: 'Jeremy' + this
.state
.listCount
.toString(),
age: '25',
id: this.state.listCount
};
listArray.push(buildObject);
let newListCount = this.state.listCount + 1;
this.setState({list: listArray, listCount: newListCount});
}
listChanged(newList) {
this.setState({
list: newList
})
}
render() {
return (
<div>
<h1>Add to List</h1>
<button onClick={this.onAddItem}>Add Item</button>
<h1>The List</h1>
<Container id={1} list={this.state.list} listChanged={this.listChanged}/>
</div>
)
}
}
export default DragDropContext(HTML5Backend)(ImageUploader);
容器:
import React, { Component } from 'react';
import update from 'react/lib/update';
import Card from './Card';
import { DropTarget } from 'react-dnd';
class Container extends Component {
constructor(props) {
super(props);
this.state = { cards: this.props.list };
}
pushCard(card) {
this.setState(update(this.state, {
cards: {
$push: [ card ]
}
}));
}
removeCard(index) {
this.setState(update(this.state, {
cards: {
$splice: [
[index, 1]
]
}
}));
}
moveCard(dragIndex, hoverIndex) {
const { cards } = this.state;
const dragCard = cards[dragIndex];
this.setState(update(this.state, {
cards: {
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragCard]
]
}
}));
}
componentWillReceiveProps(nextProps) {
// You don't have to do this check first, but it can help prevent an unneeded render
if (nextProps.list !== this.state.cards) {
this.props.listChanged(this.state.cards);
}
}
render() {
const { cards } = this.state;
const { canDrop, isOver, connectDropTarget } = this.props;
const isActive = canDrop && isOver;
const style = {
width: "200px",
height: "404px",
border: '1px dashed gray'
};
const backgroundColor = isActive ? 'lightgreen' : '#FFF';
return connectDropTarget(
<div className="houzes-dropbox">
{cards.map((card, i) => {
return (
<Card
key={card.id}
index={i}
listId={this.props.id}
card={card}
removeCard={this.removeCard.bind(this)}
moveCard={this.moveCard.bind(this)} />
);
})}
</div>
);
}
}
const cardTarget = {
drop(props, monitor, component ) {
const { id } = props;
const sourceObj = monitor.getItem();
if ( id !== sourceObj.listId ) component.pushCard(sourceObj.card);
return {
listId: id
};
}
}
export default DropTarget("CARD", cardTarget, (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
canDrop: monitor.canDrop()
}))(Container);
如果这对您有帮助,我真的很高兴。
感谢您阅读我的帖子。
弗拉基米尔
关于javascript - React DND - 拖放事件后无法将新项目添加到状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45891113/
我正在使用 从网格拖动到树 并使用 gridviewdragdrop 和 treeviewdragdrop 插件来处理页面。 一切正常,但我真的不需要拖动节点,只需要获取 dragdata 和 dro
我有一个 Jest 测试文件,其中包含许多测试。 import React from 'react'; import configureStore from 'redux-mock-store'; i
我有这些简单的表格: 1. USER_DND ╔════════╦══════╗ ║ UserID ║ DnD ║ ╠════════╬══════╣ ╚════════╩══════╝ 2. US
如何在 Android 中以编程方式打开/关闭“请勿打扰”(dnd)?是希望这会给我一些东西,但它没有: Settings.System.putInt(getContentResolver(), Se
我有 37 种不同的节点类型。 我正在尝试实现拖放。 这可行,但我需要准确限制可以拖动哪些类型以及可以删除它们的位置。 不幸的是,我在文档中找不到任何有用的信息(http://www.jstree.c
所以我正在尝试编写一个 D&D 骰子滚轮,它会拉起一个有 5 个按钮的 GUI,当按下时,会随着骰子的滚动拉出一条消息。当我单击 D4 按钮时,它会拉出消息,并且每次单击它时只会滚动 1,依此类推,其
我正在开发一个 React dnd 项目,我遵循 react-dnd documentation 。一切正常,但我无法在拖动时滚动。 当我拖动一个项目并到达最后一个可放置源时,我需要一个滚动条,然后它
有一个项目列表/表格(我相信现在没关系)。它们通过使用 jQuery 变得可拖动。我需要设置一些与被拖动的项目元素关联的数据,并能够从可放置元素的“放置”处理程序中的事件中提取它。 我尝试将 data
我编写了一个基本的 DnD 程序,其中有四个连续的 JLabel。我发觉到当我向左拖动一个标签时,它会显示在下一个标签的下方。然而,当我向右拖动标签时,它显示在下一个标签上方。标签按从左到右的顺序添加
我有一个组件当前使用 useDrag Hook 连接到 react-dnd。它运作良好,除了预览。我想实现 useDragLayer,看看它是否有助于解决我的预览问题,正如许多在线线程所建议的那样。
您好,我需要一个 DnD 解决方案来将 Outlook 邮件附件拖到 Stackpane。 JavaFX/展望 2010 stackpaneDragAndDropZone.setOnDragO
我如何在我的文件中控制台登录我有放置区域,我正在移动的节点的 ID(可拖动项目)。我相信我应该使用 monitor.getItem(),如 documentation 中指定的那样,但我不明白, 我的
看起来 React DnD 期望可拖放的项目是兄弟项目,以便正常工作。如果其中一件元素属于另一位 parent ,我会收到“预期找到有效目标”。一旦拖动事件触发(当交换应该触发时)。 我从他们的文档中
所以我为龙与地下城创建了一个基本的掷骰子 dicord 机器人。 我到目前为止的代码可以掷任何类型的骰子,(例如“roll xdy”“roll 1d20”,“roll 100d100”) 当有人发送匹
在 this Angular example ,如果将一个苹果拖到橙色部分并将其放在那里,则会出现一个动画,慢慢地将苹果返回到它原来的位置。这在视觉上传达了将苹果拖到橙色部分是无效的。使用的Angul
我正在尝试集成React DnD使用 Material UI 的 List 和 ListItem并且,拖动时,整个列表显示为拖动的元素。我已尽我所能理解这些示例,这就是我所拥有的 import Rea
我正在使用 react-beautiful-dnd 使表格行可拖动。 如果我从上到下拖动,则拖动工作正常,并且当我向上滚动页面时,它会脱离位置。 我不知道为什么。 另外,我没有发现 css 有什么奇怪
我在将组件放入应用程序的下一个列表区域时遇到困难。我可以在父列中完美地拖放和排序,但无法将组件放在其他地方。这是我的 onDragEnd 函数中的代码: onDragEnd = result =>
我目前正在尝试使用名为 dnd-kit 的拖放库 及其名为 useSortable 的钩子(Hook)。 到目前为止,我确实做到了让一切都可以按照我喜欢的方式拖动,不幸的是,不知何故我无法根据拖动更新
是否可以使用dojo工具包的dnd api更改头像的位置?此时,拖动时,被拖动项目的头像出现在鼠标光标的右侧和下方。我希望它与鼠标光标位于同一位置。我对我的应用程序进行了一些可用性测试,大多数人似乎尝
我是一名优秀的程序员,十分优秀!