Javascript 使用dnd列出未固定的项目

Javascript 使用dnd列出未固定的项目,javascript,reactjs,react-beautiful-dnd,Javascript,Reactjs,React Beautiful Dnd,我正在使用dnd并从教程中复制代码来构建一个可拖动列表。它起作用了,看起来是这样的: 下面是构建此功能的代码: 但是,现在我正在尝试实现我自己的列表,它是一个播放列表,使用输入将来自用户计算机的歌曲添加到列表中: 它部分工作,但我无法将列表项拖动到位(它总是返回到相同的顺序)。 以下是我更改的代码: 列测试.jsx export default class ColumnTest extends React.Component { constructor(props) { super(

我正在使用dnd并从教程中复制代码来构建一个可拖动列表。它起作用了,看起来是这样的:

下面是构建此功能的代码:

但是,现在我正在尝试实现我自己的列表,它是一个播放列表,使用输入将来自用户计算机的歌曲添加到列表中:

它部分工作,但我无法将列表项拖动到位(它总是返回到相同的顺序)。 以下是我更改的代码:

列测试.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>
        );
  }
}
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>
          );
     }

}
导出默认类ColumnTest扩展React.Component{
建造师(道具){
超级(道具);
this.handleClick=this.handleClick.bind(this);
this.inputRef=React.createRef();
此.state={
文件:[],
音频:'',
};
}
handleClick=事件=>{
//读取文件并返回承诺的帮助程序代码
常量读取文件=(文件)=>{
常量文件列表=[];
const fileReader=new fileReader();
//创造承诺并回报它
返回新承诺((解决、拒绝)=>{
//如果文件读取器有错误,请报告它
fileReader.onerror=(错误)=>{
拒绝({error})
}
//如果成功了,就要兑现承诺
fileReader.onload=(e)=>{
决心({
name:file.name,
链接:e.target.result
})
}
//开始读取文件
fileReader.readAsDataURL(文件);
})
}
//创建所有文件读取器承诺
//从文件列表创建一个数组,并使用映射生成
//一系列承诺
const allReaders=Array.from(event.target.files).map(readFile)
//现在处理我们刚刚创建的一系列承诺
承诺。所有(所有读者)
。然后(文件列表=>{
console.log(文件列表)
//设置我们拥有所有文件的状态
this.setState({files:fileList});
})
.catch(错误=>{
控制台错误(错误)
});
}
render(){
返回(
{this.props.column.title}
{提供=>(
{this.state.files.map((文件,索引)=>(
))}
{提供的.占位符}
)}
);
}
}
(在这里,我添加输入和fileReader,将文件添加到我的文件数组中,并使用render{}中的return()中的.map()函数迭代这些文件)

任务测试.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>
        );
  }
}
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>
          );
     }

}
导出默认类TaskTest扩展React.Component{
render(){
返回(
{(已提供,快照)=>(
{this.props.file.name}
)}
);
}
}

dnd要求您管理自己的列表,这意味着在项目“删除”后重新排序数组。要做到这一点,您需要补充以下几点:

处理“丢弃”的函数

在构造函数中绑定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;
};
您的可拖放文件周围的DragDropContext

<DragDropContext onDragEnd={this.onDragEnd}> 
    <Droppable droppableId={this.props.column.id}>
    ...

...

您可以在这里查看一个示例:

好的,我喜欢这个。我如何将我的文件数组添加到代码沙盒中的代码中?我想我是用你的代码实现的。谢谢你,先生。