使用 react-beautiful-dnd 列出不在原地的项目
List items not staying in place using react-beautiful-dnd
我正在使用 react-beautiful-dnd 并从教程中复制代码来构建可拖动列表。它有效并且看起来像这样:
这是构建它的代码:https://github.com/DDavis1025/react-beautiful-dnd
但是现在我正在尝试实现我自己的列表,这是一个播放列表,它使用输入将用户计算机中的歌曲添加到列表中:
部分有效,但我无法将列表项拖动到位(它总是回到相同的顺序)。
这是我更改的代码:
列-test.jsx
export default class ColumnTest extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.inputRef = React.createRef();
this.state = {
files: [],
audio: '',
};
}
handleClick = event => {
// Helper code to read file and return promise
const readFile = (file) => {
const fileList = [];
const fileReader = new FileReader();
// create the promise and return it
return new Promise((resolve, reject) => {
// if file reader has an error, report it
fileReader.onerror = (error) => {
reject({ error })
}
// if success, resolve the promise
fileReader.onload = (e) => {
resolve({
name: file.name,
link: e.target.result
})
}
// start reading the file
fileReader.readAsDataURL(file);
})
}
// create all the file reader promises
// create an array from the files list and use map to generate
// an array of promises
const allReaders = Array.from(event.target.files).map(readFile)
// Now handle the array of promises we just created
Promise.all(allReaders)
.then(fileList => {
console.log(fileList)
// set the state that we have all the files
this.setState({ files: fileList });
})
.catch(error => {
console.error(error)
});
}
render() {
return (
<div className="downloadMusic">
<div className="input">
<input
onChange={this.handleClick}
id="upload-file"
className="inputName"
type="file"
multiple
ref={this.inputRef}
/>
</div>
<div className="audio-player">
<audio
controls
autoPlay
src={this.state.audio}
/>
</div>
<Container>
<Title>{this.props.column.title}</Title>
<Droppable droppableId={this.props.column.id}>
{provided => (
<TaskList
ref={provided.innerRef} {...provided.droppableProps}>
{this.state.files.map((file, index) => (
<TaskTest key={file.link} file={file} index={index} />
))}
{provided.placeholder}
</TaskList>
)}
</Droppable>
</Container>
</div>
);
}
}
(这是我添加输入和 fileReader 以将文件添加到我的文件数组并使用 .map() 函数在 return() in render{} 中迭代这些文件的地方)
任务-test.jsx
export default class TaskTest extends React.Component {
render() {
return (
<Draggable draggableId={this.props.file.link} index={this.props.index}>
{(provided, snapshot) => (
<Container
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
isDragging={snapshot.isDragging}
>
{this.props.file.name}
</Container>
)}
</Draggable>
);
}
}
react-beautiful-dnd 要求您管理自己的列表,这意味着在一个项目 "dropped" 之后重新排序数组。做到这一点,您需要添加一些东西:
一个函数来处理"drop"
onDragEnd(result) {
// dropped outside the list
if (!result.destination) {
return;
}
const files = reorder(
this.state.files,
result.source.index,
result.destination.index
);
this.setState({
files
});
}
在构造函数中绑定 onDragEnd
this.onDragEnd = this.onDragEnd.bind(this);
重新排序数组的函数
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
你的 droppable 周围的 DragDropContext
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId={this.props.column.id}>
...
您可以在此处查看示例:https://codesandbox.io/s/k260nyxq9v
我正在使用 react-beautiful-dnd 并从教程中复制代码来构建可拖动列表。它有效并且看起来像这样:
这是构建它的代码:https://github.com/DDavis1025/react-beautiful-dnd
但是现在我正在尝试实现我自己的列表,这是一个播放列表,它使用输入将用户计算机中的歌曲添加到列表中:
部分有效,但我无法将列表项拖动到位(它总是回到相同的顺序)。 这是我更改的代码:
列-test.jsx
export default class ColumnTest extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.inputRef = React.createRef();
this.state = {
files: [],
audio: '',
};
}
handleClick = event => {
// Helper code to read file and return promise
const readFile = (file) => {
const fileList = [];
const fileReader = new FileReader();
// create the promise and return it
return new Promise((resolve, reject) => {
// if file reader has an error, report it
fileReader.onerror = (error) => {
reject({ error })
}
// if success, resolve the promise
fileReader.onload = (e) => {
resolve({
name: file.name,
link: e.target.result
})
}
// start reading the file
fileReader.readAsDataURL(file);
})
}
// create all the file reader promises
// create an array from the files list and use map to generate
// an array of promises
const allReaders = Array.from(event.target.files).map(readFile)
// Now handle the array of promises we just created
Promise.all(allReaders)
.then(fileList => {
console.log(fileList)
// set the state that we have all the files
this.setState({ files: fileList });
})
.catch(error => {
console.error(error)
});
}
render() {
return (
<div className="downloadMusic">
<div className="input">
<input
onChange={this.handleClick}
id="upload-file"
className="inputName"
type="file"
multiple
ref={this.inputRef}
/>
</div>
<div className="audio-player">
<audio
controls
autoPlay
src={this.state.audio}
/>
</div>
<Container>
<Title>{this.props.column.title}</Title>
<Droppable droppableId={this.props.column.id}>
{provided => (
<TaskList
ref={provided.innerRef} {...provided.droppableProps}>
{this.state.files.map((file, index) => (
<TaskTest key={file.link} file={file} index={index} />
))}
{provided.placeholder}
</TaskList>
)}
</Droppable>
</Container>
</div>
);
}
}
(这是我添加输入和 fileReader 以将文件添加到我的文件数组并使用 .map() 函数在 return() in render{} 中迭代这些文件的地方)
任务-test.jsx
export default class TaskTest extends React.Component {
render() {
return (
<Draggable draggableId={this.props.file.link} index={this.props.index}>
{(provided, snapshot) => (
<Container
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
isDragging={snapshot.isDragging}
>
{this.props.file.name}
</Container>
)}
</Draggable>
);
}
}
react-beautiful-dnd 要求您管理自己的列表,这意味着在一个项目 "dropped" 之后重新排序数组。做到这一点,您需要添加一些东西:
一个函数来处理"drop"
onDragEnd(result) {
// dropped outside the list
if (!result.destination) {
return;
}
const files = reorder(
this.state.files,
result.source.index,
result.destination.index
);
this.setState({
files
});
}
在构造函数中绑定 onDragEnd
this.onDragEnd = this.onDragEnd.bind(this);
重新排序数组的函数
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
你的 droppable 周围的 DragDropContext
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId={this.props.column.id}>
...
您可以在此处查看示例:https://codesandbox.io/s/k260nyxq9v