You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React拖拽功能实现报错求助:children is not a function及替代库推荐

解决react-beautiful-dnd的"children is not a function"错误及替代库推荐

错误原因与修复方案

核心问题分析

  1. <Draggable>组件要求子元素为函数:react-beautiful-dnd的<Draggable>必须接收一个函数作为子元素,用来获取拖拽相关的props(如draggableProps、dragHandleProps),你当前代码直接将普通组件作为子元素,触发了该错误。
  2. <Droppable>用法错误:<Droppable>是容器组件,应包裹一组可拖拽项,而非给每个拖拽项单独套一层<Droppable>。

修复后的代码

可拖拽组件(TaskCard)

import { useState } from 'react';
import { Draggable } from 'react-beautiful-dnd';
import { Card, CardContent } from '@mui/material';

const TaskCard = ({ id, name, description, index }) => {
  return (
    <Draggable
      draggableId={id}
      index={index}
    >
      {(provided, snapshot) => (
        <Card
          style={{ 
            marginBottom: "15px",
            opacity: snapshot.isDragging ? 0.5 : 1
          }}
          {...provided.draggableProps}
          {...provided.dragHandleProps}
          ref={provided.innerRef}
        >
          <CardContent>
            <h4>{name}</h4>
            <p>{description}</p>
          </CardContent>
        </Card>
      )}
    </Draggable>
  );
};

export default TaskCard;

可放置容器组件

import { Droppable } from 'react-beautiful-dnd';
import { Card, CardHeader, CardContent, IconButton } from '@mui/material';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import TaskCard from './TaskCard';

const TaskContainer = ({ title, tasks }) => {
  return (
    <Card className={classes.cont}>
      <CardHeader
        title={title}
        action={
          <IconButton>
            <MoreVertIcon />
          </IconButton>
        }
      />
      <hr />
      <CardContent>
        <Droppable droppableId="task-container">
          {(provided) => (
            <div
              {...provided.droppableProps}
              ref={provided.innerRef}
            >
              {tasks.map((task, index) => (
                <TaskCard
                  key={task.id}
                  id={task.id}
                  name={task.name}
                  description={task.description}
                  index={index}
                />
              ))}
              {provided.placeholder}
            </div>
          )}
        </Droppable>
      </CardContent>
      <hr />
      <CardContent>Button</CardContent>
    </Card>
  );
};

export default TaskContainer;

关键修复点

  • 将<Draggable>的子元素改为函数,接收provided和snapshot参数,把拖拽props绑定到可交互的DOM元素上。
  • 用单个<Droppable>包裹所有<Draggable>,并添加provided.placeholder处理拖拽时的布局占位。
  • 给<Draggable>传递index参数,这是库要求的必填项,用于计算拖拽位置。

简便替代库推荐

如果觉得react-beautiful-dnd的API过于繁琐,可以考虑以下更轻量化的选择:

  • @dnd-kit:模块化拖拽库,API简洁直观,支持多种拖拽模式,原生适配React 18,文档清晰,适合大多数现代React项目。
  • react-sortable-hoc:专注于列表排序场景,API极简,快速实现拖拽排序需求,学习成本极低。
  • react-dnd:老牌拖拽库,灵活性极强,适合复杂拖拽逻辑场景,但学习曲线略陡。

内容的提问来源于stack exchange,提问作者Martin Wcr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:35:08