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

如何在styled component中使用React DnD?遇连接器报错求替代方案

How to Use React DnD with Styled Components (Without Wrapping in a Div)

Hey there, I totally get your frustration—wrapping your styled component in a <div> can mess up carefully crafted layouts, so let's dive into that second solution the error mentions: turning your styled component into a drag source (or drop target) directly.

What the Error Means

React DnD's connectors need to attach to either native DOM elements or components explicitly set up as drag/drop targets. When you tried wrapping your PaneItemText__StyledItem with connectDragSource, you were passing a styled component (a React component, not a native element) to the connector—hence the error. Instead, we need to make the styled component itself the drag source.

Step-by-Step Solution (Function Components with Hooks)

This is the modern approach using React DnD's useDrag hook:

  1. Create your styled component as usual:
import styled from 'styled-components';
import { useDrag } from 'react-dnd';

const StyledItem = styled.div`
  // Your existing styles here
  padding: 1rem;
  background: #f0f0f0;
  border-radius: 4px;
  cursor: grab;
`;
  1. Build a draggable component that binds useDrag to your styled component:
    Instead of wrapping the styled component with connectDragSource, we'll use the ref returned by useDrag to attach drag functionality directly to the styled component:
const DraggableItem = ({ itemData }) => {
  // Use useDrag to get the drag ref and state
  const [{ isDragging }, dragRef] = useDrag({
    // Define your unique drag type string
    type: 'LIST_ITEM',
    // Data to pass when dragging starts
    item: { id: itemData.id, content: itemData.content },
    // Collect drag state for dynamic styling
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
  });

  // Bind the drag ref to your styled component, add dynamic styles if needed
  return (
    <StyledItem
      ref={dragRef}
      style={{ opacity: isDragging ? 0.6 : 1 }}
    >
      {itemData.content}
    </StyledItem>
  );
};

For Class Components (Using Higher-Order Components)

If you're still using class components, wrap your styled component directly with React DnD's DragSource HOC instead of wrapping an instance of it:

import styled from 'styled-components';
import { DragSource } from 'react-dnd';

const StyledItem = styled.div`
  // Your styles here
`;

// Define drag source logic
const dragSourceSpec = {
  beginDrag(props) {
    return { id: props.item.id };
  },
};

// Collect drag state and connector
function collectDrag(connect, monitor) {
  return {
    connectDragSource: connect.dragSource(),
    isDragging: monitor.isDragging(),
  };
}

// Wrap the StyledItem directly with DragSource
const DraggableItem = DragSource('LIST_ITEM', dragSourceSpec, collectDrag)(StyledItem);

// Use it like:
// <DraggableItem item={yourItemData} />

Why This Works

By attaching the drag source logic directly to your styled component, you're telling React DnD that this component is a valid drag source. Styled components render a native DOM element under the hood, so the connector can attach to that element without needing an extra wrapper <div>. This keeps your layout intact while adding the drag functionality.

Just ensure your styled component is based on a native HTML element (like div, span, etc.)—which it almost certainly is, since styled-components defaults to div if you don't specify another element.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:59:42