MST

星途 面试题库

面试题:React中如何处理基本的拖放事件并应用于简单列表场景

假设你有一个包含多个待办事项的列表,每个待办事项是一个React组件。请使用React实现将待办事项从一个列表拖放到另一个列表的功能。请描述实现思路,并给出关键代码片段,包括如何绑定拖放事件、传递数据等。
15.7万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. HTML5拖放API:利用HTML5提供的拖放API来实现基本的拖放功能。在React中,通过在组件的render方法中为相应元素绑定拖放事件的处理函数。
  2. 状态管理:使用React的状态来管理待办事项在不同列表中的位置。当拖放操作发生时,更新状态以反映待办事项的新位置。
  3. 传递数据:在拖放过程中,通过dataTransfer对象来传递待办事项的数据。

关键代码片段

  1. 定义待办事项组件
import React from 'react';

const TodoItem = ({ id, text, onDragStart }) => {
    return (
        <li
            draggable={true}
            onDragStart={(e) => {
                e.dataTransfer.setData('text/plain', id);
                onDragStart(id);
            }}
        >
            {text}
        </li>
    );
};

export default TodoItem;
  1. 定义列表组件
import React, { useState } from'react';
import TodoItem from './TodoItem';

const TodoList = ({ list, onDrop, onDragOver, onDragStart }) => {
    return (
        <ul
            onDrop={onDrop}
            onDragOver={onDragOver}
        >
            {list.map(item => (
                <TodoItem
                    key={item.id}
                    id={item.id}
                    text={item.text}
                    onDragStart={onDragStart}
                />
            ))}
        </ul>
    );
};

export default TodoList;
  1. 主组件
import React, { useState } from'react';
import TodoList from './TodoList';

const App = () => {
    const [list1, setList1] = useState([
        { id: 1, text: '事项1' },
        { id: 2, text: '事项2' }
    ]);
    const [list2, setList2] = useState([
        { id: 3, text: '事项3' },
        { id: 4, text: '事项4' }
    ]);

    const onDragStart = (id) => {
        // 可以在这里记录开始拖动的事项id等操作
    };

    const onDragOver = (e) => {
        e.preventDefault();
    };

    const onDrop = (e, targetList) => {
        e.preventDefault();
        const itemId = e.dataTransfer.getData('text/plain');
        const sourceList = targetList === 'list1'? list2 : list1;
        const target = targetList === 'list1'? setList1 : setList2;
        const newSourceList = sourceList.filter(item => item.id!== parseInt(itemId));
        const draggedItem = sourceList.find(item => item.id === parseInt(itemId));
        target([...targetList === 'list1'? list1 : list2, draggedItem]);
        if (targetList === 'list1') {
            setList2(newSourceList);
        } else {
            setList1(newSourceList);
        }
    };

    return (
        <div>
            <h1>列表1</h1>
            <TodoList
                list={list1}
                onDrop={(e) => onDrop(e, 'list1')}
                onDragOver={onDragOver}
                onDragStart={onDragStart}
            />
            <h1>列表2</h1>
            <TodoList
                list={list2}
                onDrop={(e) => onDrop(e, 'list2')}
                onDragOver={onDragOver}
                onDragStart={onDragStart}
            />
        </div>
    );
};

export default App;