React DnD Preview Component
react-dnd-preview is a dedicated component for creating drag-and-drop previews within applications utilizing React DnD. It simplifies the implementation of visual feedback during drag operations by providing a component that renders the dragged item at the current mouse position. The current stable version is 9.0.0, which includes support for React v19. Releases typically follow the React and React DnD release cycles for major versions, with minor and patch updates for bug fixes and dependency bumps occurring more frequently. Its key differentiator is its tight integration with the React DnD ecosystem, offering a straightforward way to add preview functionality without complex manual DOM manipulation, making it an essential companion for sophisticated drag-and-drop UIs.
Common errors
-
Error [ERR_REQUIRE_ESM]: require() of ES Module .../node_modules/react-dnd-preview/dist/index.js from ... not supported.
cause Attempting to use CommonJS `require()` syntax with `react-dnd-preview` in a project that doesn't transpile it, after the library became ESM-only in v8.0.0.fixUpdate your import statements to use ES Modules syntax: `import { Preview } from 'react-dnd-preview';` and ensure your bundler (Webpack, Rollup, Vite) is configured for ESM. -
TypeError: Cannot read properties of undefined (reading 'currentOffset')
cause This error often indicates that `react-dnd-preview` is trying to access drag monitor state before a drag operation has properly begun or after it has ended, or if the DndProvider is not correctly set up.fixEnsure that `react-dnd`'s `DndProvider` is wrapping your components, and that `react-dnd-preview`'s `Preview` component is rendered within it. Verify your `generator` function handles all expected item types and states correctly. -
TS2307: Cannot find module 'react-dnd-preview' or its corresponding type declarations.
cause TypeScript cannot locate the type definitions for the `react-dnd-preview` package.fixEnsure `react-dnd-preview` is installed correctly and your `tsconfig.json` includes `node_modules` in its `typeRoots` or `types` configuration. Sometimes, a simple reinstall (`npm install react-dnd-preview`) or IDE restart helps.
Warnings
- breaking Version 9.0.0 introduces support for React v19. While no explicit breaking changes are noted for `react-dnd-preview` itself, ensure your `react` peer dependency aligns with v19 if upgrading, as this is a major ecosystem shift.
- breaking Version 8.0.0 dropped support for CommonJS and UMD builds, making the library ESM-only. Direct `require()` statements will no longer work and will result in runtime errors.
- breaking Version 8.0.0 also upgraded `react-dnd` to `16.0.1` and dropped support for Node.js 14. Ensure your project's `react-dnd` version is compatible and your Node.js environment is v16 or higher.
- gotcha Starting with version 8.0.2, you might need to explicitly add `dnd-core` as a dependency in your project, even though it's typically an indirect dependency of `react-dnd`.
- gotcha The `Preview` component allows changing its placement via a `placement` prop since v8.1.0, enabling more flexible positioning than the default mouse tracking.
Install
-
npm install react-dnd-preview -
yarn add react-dnd-preview -
pnpm add react-dnd-preview
Imports
- Preview
const Preview = require('react-dnd-preview');import { Preview } from 'react-dnd-preview'; - usePreview
import usePreview from 'react-dnd-preview';
import { usePreview } from 'react-dnd-preview'; - PreviewGenerator
import type { PreviewGenerator } from 'react-dnd-preview';
Quickstart
import React from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { useDrag } from 'react-dnd';
import { Preview } from 'react-dnd-preview';
const DraggableBox: React.FC = () => {
const [{ isDragging }, drag] = useDrag(() => ({
type: 'BOX',
item: { id: 'some-item' },
collect: (monitor) => ({
isDragging: monitor.isDragging()
})
}));
return (
<div
ref={drag}
style={{
opacity: isDragging ? 0.5 : 1,
cursor: 'move',
width: '100px',
height: '100px',
border: '1px solid black',
backgroundColor: 'lightblue',
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}}
>
Drag Me
</div>
);
};
const generatePreview = ({ itemType, item, style }) => {
if (itemType === 'BOX') {
return (
<div style={{ ...style, backgroundColor: 'orange', padding: '10px', borderRadius: '5px' }}>
Previewing {item.id}
</div>
);
}
return null;
};
const App: React.FC = () => {
return (
<DndProvider backend={HTML5Backend}>
<div style={{ padding: '20px' }}>
<h1>React DnD Preview Example</h1>
<DraggableBox />
<Preview generator={generatePreview} />
</div>
</DndProvider>
);
};
export default App;