gpt4 book ai didi

javascript - 如何在 React 中实现拖放行为

转载 作者:行者123 更新时间:2023-12-05 07:22:04 25 4
gpt4 key购买 nike

我正在尝试使用 React 和 react-beautiful-dnd 实现拖放行为图书馆。

我想使用 react-dropzone 选择一些图像库,选择图像后我在屏幕右侧显示缩略图,之后我希望能够将其中一个缩略图拖到左侧并将其放到其中一个容器中。

我的代码如下:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import Dropzone from "react-dropzone";
import { Animated } from "react-animated-css";
import { orderBy } from "lodash";
import UUID from "uuid";
import "./styles.css";

const animationIn = "fadeInDown";
const animationOut = "fadeOutUp";
const animationDuration = 400; // in ms

const pictureTypes = [
{
title: "3/4 front left",
imageOverlay: "https://via.placeholder.com/100",
item: "front-left",
mandatory: true,
image: null,
priority: 1
},
{
title: "3/4 rear right",
imageOverlay: "https://via.placeholder.com/100",
item: "rear-right",
mandatory: true,
image: null,
priority: 2
},
{
title: "Inside door right",
imageOverlay: "https://via.placeholder.com/100",
item: "front-door-right-i",
mandatory: true,
image: null,
priority: 3
}
];

class App extends Component {
constructor(props) {
super(props);

this.state = {
files: [],
pictureTypes: pictureTypes
};

this.onDragEnd = this.onDragEnd.bind(this);
}

onDragEnd(result) {
debugger;
// dropped outside the list
if (!result.destination) {
return;
}
}

addFilesToState(files) {
let files_with_preview = [];
files.map(file => {
file["preview"] = URL.createObjectURL(file);
files_with_preview.push(file);
this.setState({ [`visibleAnimate${file.path}`]: true });
});

const new_files = [...this.state.files, ...files_with_preview];
this.setState({ files: new_files });
}

renderPreviews(files) {
if (files.length < 1)
return <div>Drag and drop some files to see them here.</div>;

return (
<div style={{ display: "flex", flexDirection: "column" }}>
<div>Chosen pictures</div>
<div style={{ display: "flex", flexDirection: "row" }}>
{files.map((file, index) => {
return (
<Draggable key={UUID.v4()} draggableId={UUID.v4()} index={index}>
{provided => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<img
src={file.preview}
alt={file.path}
style={{ width: 80 }}
/>
</div>
)}
</Draggable>
);
})}
</div>
</div>
);
}

handlePictureTypesDrop(file, pictureType) {
const file_blob = URL.createObjectURL(file);
const updated_picture_type = {
...this.state.pictureTypes.find(pt => pt.item === pictureType.item),
image: file_blob
};
const updated_picture_types = [
...this.state.pictureTypes.filter(pt => pt.item !== pictureType.item),
updated_picture_type
];
let new_picture_types = [...updated_picture_types];

this.setState({ pictureTypes: new_picture_types });
}

renderPictureTypes() {
const { allowed_types } = this.props;
const { pictureTypes } = this.state;
const self = this;

return orderBy(pictureTypes, "priority").map(pt => {
return (
<div style={{ width: "25%", marginRight: 5 }}>
<Dropzone
onDrop={files => self.handlePictureTypesDrop(files[0], pt)}
accept={allowed_types}
multiple={false}
>
{({ getRootProps, getInputProps }) => (
<div {...getRootProps()}>
<input {...getInputProps()} />
<div className="picture-types-wrapper">
<div>
<img
src={pt.image !== null ? pt.image : pt.imageOverlay}
alt={pt.title}
/>
</div>
<div style={{ fontSize: "0.65rem" }}>{pt.title}</div>
</div>
</div>
)}
</Dropzone>
</div>
);
});
}

// Normally you would want to split things out into separate components.
// But in this example everything is just done in one place for simplicity
render() {
const { files } = this.state;
const self = this;
return (
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId="droppable">
{provided => (
<div
key="droppable"
{...provided.droppableProps}
ref={provided.innerRef}
>
<Dropzone
onDrop={files => self.addFilesToState(files)}
accept="image/jpeg, image/png"
>
{({ getRootProps, getInputProps }) => (
<section className="drag-drop-section">
<div {...getRootProps()}>
<input {...getInputProps()} />
<p className="drag-drop-text">
Drag 'n' drop some files here, or click to select files
</p>
</div>
</section>
)}
</Dropzone>

<div
style={{ display: "flex", flexDirection: "row", marginTop: 10 }}
>
<div style={{ display: "flex", flexDirection: "row" }}>
{self.renderPictureTypes()}
</div>
<div className="flex w-1/2 pl-2">
{self.renderPreviews(files)}
</div>
</div>
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
);
}
}

// Put the thing into the DOM!
ReactDOM.render(<App />, document.getElementById("root"));

Here is the example code on codesandbox.

照片已成功添加到我渲染缩略图的右侧,但我无法将其中一张拖到左侧。

知道怎么解决吗?

最佳答案

<Draggable>应该在<Droppable>里面

<Draggable /> components can be dragged around and dropped onto <Droppable />s. A <Draggable /> must always be contained within a <Droppable />. It is possible to reorder a <Draggable /> within its home <Droppable /> or move to another <Droppable />. It is possible because a <Droppable /> is free to control what it allows to be dropped on it.see here

关于javascript - 如何在 React 中实现拖放行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56643338/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com