{"id":28334,"date":"2022-04-28T14:40:08","date_gmt":"2022-04-28T14:40:08","guid":{"rendered":"http:\/\/how-to-rearrange-gallery-images-using-react-dnd"},"modified":"2025-02-15T12:02:36","modified_gmt":"2025-02-15T20:02:36","slug":"how-to-rearrange-gallery-images-using-react-dnd","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/","title":{"rendered":"How to Rearrange Gallery Images Using React DnD"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>React drag and drop (React DnD) is a beautiful and accessible drag and drop library made for React apps that let\u2019s build interactive experiences. It supports touch interactions on mobile devices and HTML5, but it depends on <a href=\"https:\/\/react-dnd.github.io\/react-dnd\/about#touch-support\">touch support<\/a>. One popular app that uses this drag and drop interaction is Trello.<\/p>\n<p>In this post, we will learn how to build a page filled with images that allow anyone to move an image around to another position within the app in response to the drag and drop events.<\/p>\n<p>The complete project is on <a href=\"https:\/\/codesandbox.io\/s\/keen-zhukovsky-w4z2pq\">CodeSandbox<\/a>.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\"><\/code><\/span><\/pre>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/keen-zhukovsky-w4z2pq?theme=dark&amp;codemirror=1&amp;highlights=&amp;editorsize=50&amp;fontsize=14&amp;expanddevtools=0&amp;hidedevtools=0&amp;eslint=0&amp;forcerefresh=0&amp;hidenavigation=0&amp;initialpath=%2F&amp;module=&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"rearrange gallery images\"\n      loading=\"lazy\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ><\/iframe>\n  <\/div>\n\n  <div class=\"wp-block-cloudinary-markdown \"><pre class=\"js-syntax-highlighted\"><code>\n## Prerequisites\n\nTo complete the exercise in this post, we need the following:\n\n- Basic knowledge of JavaScript and React.\n- Node.js installed on our computer.\n\n\n## Getting Started\n\nReact is a JavaScript frontend library for generating and building user interfaces for web applications.\n\nTo scaffold a new project, run the following command in our terminal:\n\n\n```sh\nnpx create-react-app &lt;project-name&gt;\n<\/code><\/pre>\n<p>After the installation, navigate to the created directory and run the command below to start the application:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">cd &lt;project-name&gt; <span class=\"hljs-comment\"># navigate to the directory <\/span>\n\nnpm run start <span class=\"hljs-comment\"># run the development server<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>React.js starts the development environment on <code>http:\/\/localhost:3000<\/code>.<\/p>\n<p>With the whole setup done, run either of the commands below to install the <code>react-dnd<\/code> ****and ****<code>react-dnd-html5-backend<\/code> libraries to our project:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">yarn add react-dnd react-dnd-html5-backend\n    \n<span class=\"hljs-comment\"># or <\/span>\n    \nnpm install react-dnd react-dnd-html5-backend\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><code>react-dnd-html5-backend<\/code>: This library will allow the use of the drag and drop API with <code>react``-``dnd<\/code>.<\/p>\n<p>Now, let\u2019s implement the drag and drop functionality in the project\u2019s entry point , <code>index.js<\/code> , with the provider component.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ src\/index.js<\/span>\n<span class=\"hljs-comment\">\/\/ other imports<\/span>\n    \n<span class=\"hljs-comment\">\/\/ add this<\/span>\n<span class=\"hljs-keyword\">import<\/span> { DndProvider } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-dnd\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { HTML5Backend } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-dnd-html5-backend\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> App <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/App\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">\".\/styles.css\"<\/span>;\n    \n<span class=\"hljs-keyword\">const<\/span> rootElement = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"root\"<\/span>);\n<span class=\"hljs-keyword\">const<\/span> root = createRoot(rootElement);\n\nroot.render(\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">StrictMode<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">DndProvider<\/span> <span class=\"hljs-attr\">backend<\/span>=<span class=\"hljs-string\">{HTML5Backend}<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">App<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">DndProvider<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">StrictMode<\/span>&gt;<\/span><\/span>\n);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>In the code block above, we wrap the highest order component, <code>App<\/code>, with a provider that comes with the React DnD library. The provider serves to alert the library that the component inside the provider will have access to the library\u2019s functionality.  Also, we pass in the <code>backend<\/code> property, which is the primary backend support for the touch support.<\/p>\n<h2>Project: Gallery Images<\/h2>\n<p>To have access to the image on the page, we will start with creating a list of images in our app that will have the ability to drag and drop the desired image.<\/p>\n<p>We won\u2019t be diving deep into building the gallery image app from scratch for this post. However, we will focus our attention more on the functionality of using the React DnD library to rearrange the image.<\/p>\n<p>Now, create an array of objects that contains the data.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-comment\"># src\/data.js<\/span>\nexport <span class=\"hljs-keyword\">default<\/span> &#91;\n  {\n    id: <span class=\"hljs-number\">1<\/span>,\n    title: <span class=\"hljs-string\">'Travel'<\/span>,\n    img:\n      <span class=\"hljs-string\">'https:\/\/media.istockphoto.com\/photos\/beautiful-view-of-amazing-sandstone-formations-in-famous-lower-near-picture-id807387518?k=20&amp;m=807387518&amp;s=612x612&amp;w=0&amp;h=G8O867Id71Sk6LCiAnAYp-dIu9uf4YqlfnO3uj-SQ00='<\/span>\n   },\n...\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>As pointed out earlier, we won\u2019t be focusing much on the styling of the app. Create a new file in the <code>src<\/code> folder called <code>styles.css<\/code> and paste the following code from this <a href=\"https:\/\/gist.github.com\/Terieyenike\/e5106719f894c85da535192865316455\">gist<\/a>.<\/p>\n<p>Next, let\u2019s loop through the resulting data objects in the <code>App.js<\/code> file to see the gallery images from the <code>Card<\/code> component by passing props. Add the following code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ src\/App.js<\/span>\n<span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> galleryList <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/data.js\"<\/span>;\n    \n<span class=\"hljs-keyword\">const<\/span> Card = <span class=\"hljs-function\">(<span class=\"hljs-params\">{src, title, id, index}<\/span>) =&gt;<\/span> {\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"card\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{src}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{title}<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n};\n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> &#91;images, setImages] = React.useState(galleryList);\n      \n<span class=\"hljs-keyword\">return<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n    {React.Children.toArray(\n      images.map((image, index) =&gt; (\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Card<\/span>\n          <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{image.img}<\/span>\n          <span class=\"hljs-attr\">title<\/span>=<span class=\"hljs-string\">{image.title}<\/span>\n          <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">{image.id}<\/span>\n          <span class=\"hljs-attr\">index<\/span>=<span class=\"hljs-string\">{index}<\/span>\n        \/&gt;<\/span>\n      ))\n    )}\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/span>\n);\n};\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The result from the above should look like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_7672E199EC7800126C5ECD69774B16791DD8D435B636DB6CD4636935243DBD18_1651153041672_screenshoot+on+unc.PNG\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1903\" height=\"883\"\/><\/p>\n<h2>Implementing Drag and Drop on Images with React DnD<\/h2>\n<p>With the library present in our app, we import the <code>useDrag<\/code> hook from React DnD.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ src\/App.js<\/span>\n<span class=\"hljs-comment\">\/\/ react import<\/span>\n<span class=\"hljs-keyword\">import<\/span> { useDrag} <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-dnd\"<\/span>;\n<span class=\"hljs-comment\">\/\/ image data objects import<\/span>\n    \n<span class=\"hljs-keyword\">const<\/span> Card = <span class=\"hljs-function\">(<span class=\"hljs-params\">{src, title, id, index}<\/span>) =&gt;<\/span> {\n<span class=\"hljs-keyword\">const<\/span> ref = React.useRef(<span class=\"hljs-literal\">null<\/span>); \n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"card\"<\/span>&gt;<\/span>\n        \/\/ card images\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n};\n\n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-comment\">\/\/ state <\/span>\n<span class=\"hljs-keyword\">const<\/span> &#91;{ isDragging }, drag] = useDrag({\n    <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">\"image\"<\/span>,\n    <span class=\"hljs-attr\">item<\/span>: <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-keyword\">return<\/span> { id, index };\n    },\n    <span class=\"hljs-attr\">collect<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">monitor<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-keyword\">return<\/span> {\n        <span class=\"hljs-attr\">isDragging<\/span>: monitor.isDragging()\n      };\n    }\n});\n    \n<span class=\"hljs-keyword\">return<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n    \/\/ loop through the images in Card component\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/span>\n);\n};\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>In the above code block, it does the following:<\/p>\n<ul>\n<li>\n<code>useRef<\/code>: This hook returns a mutable <code>ref<\/code> object when initialized to the passed argument with a <code>.current<\/code> property.<\/li>\n<li>\n<code>useDrag<\/code>: The hook is used on every element to make it draggable. Using the <code>useDrag<\/code> hook comes with a set of properties.<\/li>\n<li>\n<code>isDragging<\/code>: A boolean variable that determines if we are currently dragging an image or not. It returns <code>true<\/code> if we are dragging the image and false if otherwise.<\/li>\n<li>\n<code>drag<\/code>: Used to reference the element we want to make draggable.<\/li>\n<li>\n<code>type<\/code>: Every element in <strong>React DnD<\/strong> requires an identifier which is a string.<\/li>\n<li>\n<code>item<\/code>: It describes the item (<code>id<\/code> and <code>index<\/code>) property that match the drop targets about the drag source.<\/li>\n<li>\n<code>collect<\/code>: The property contains a callback function that receives the <code>isDragging<\/code> props and <code>monitor<\/code> parameter.<\/li>\n<li>\n<code>monitor<\/code>: It allows you update the props of your components in response to the drag and drop state changes.<\/li>\n<\/ul>\n<h2>Defining a Drop Area<\/h2>\n<p>Let\u2019s import the <code>useDrop<\/code> component from the <strong>React DnD<\/strong> library.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ src\/App.js<\/span>\n<span class=\"hljs-keyword\">import<\/span> { useDrag, useDrop } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-dnd\"<\/span>;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><code>useDrop<\/code>: This hook acts as a drop target in our component into the DnD system.<\/p>\n<p>Next, update and add the following code in the <code>App.js<\/code> file:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ React import<\/span>\n<span class=\"hljs-keyword\">import<\/span> { useDrag, useDrop } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-dnd\"<\/span>;\n    \n<span class=\"hljs-comment\">\/\/ data image import<\/span>\n    \n<span class=\"hljs-keyword\">const<\/span> Card = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ src, title, id, index }<\/span>) =&gt;<\/span> {\n<span class=\"hljs-keyword\">const<\/span> ref = React.useRef(<span class=\"hljs-literal\">null<\/span>);\n    \n<span class=\"hljs-keyword\">const<\/span> &#91;, drop] = useDrop({\n  <span class=\"hljs-attr\">accept<\/span>: <span class=\"hljs-string\">\"image\"<\/span>,\n  <span class=\"hljs-attr\">hover<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">item, monitor<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-keyword\">if<\/span> (!ref.current) {\n      <span class=\"hljs-keyword\">return<\/span>;\n    }\n<span class=\"hljs-keyword\">const<\/span> dragIndex = item.index;\n<span class=\"hljs-keyword\">const<\/span> hoverIndex = index;\n\n<span class=\"hljs-keyword\">if<\/span> (dragIndex === hoverIndex) {\n            <span class=\"hljs-keyword\">return<\/span>;\n}\n<span class=\"hljs-keyword\">const<\/span> hoverBoundingRect = ref.current?.getBoundingClientRect();\n<span class=\"hljs-keyword\">const<\/span> hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) \/ <span class=\"hljs-number\">2<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> clientOffset = monitor.getClientOffset();\n<span class=\"hljs-keyword\">const<\/span> hoverClientY = clientOffset.y - hoverBoundingRect.top;\n\n<span class=\"hljs-keyword\">if<\/span> (dragIndex &lt; hoverIndex &amp;&amp; hoverClientY &lt; hoverMiddleY) {\n     <span class=\"hljs-keyword\">return<\/span>;\n}\n\n<span class=\"hljs-keyword\">if<\/span> (dragIndex &gt; hoverIndex &amp;&amp; hoverClientY &gt; hoverMiddleY) {\n    <span class=\"hljs-keyword\">return<\/span>;\n}\n\nmoveImage(dragIndex, hoverIndex);\n\nitem.index = hoverIndex;\n\n}\n});\n      \n<span class=\"hljs-comment\">\/\/ useDrag component<\/span>\n    \n<span class=\"hljs-keyword\">const<\/span> opacity = isDragging ? <span class=\"hljs-number\">0<\/span> : <span class=\"hljs-number\">1<\/span>;\ndrag(drop(ref));\n\n<span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">ref<\/span>=<span class=\"hljs-string\">{ref}<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">opacity<\/span> }} <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"card\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{src}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{title}<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n);\n}\n    \n<span class=\"hljs-comment\">\/\/ App component<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The above code does the following:<\/p>\n<ul>\n<li>\n<strong>drop<\/strong>:  It is called when a compatible item on the app is dropped on the target.<\/li>\n<li>\n<strong>hover(item, monitor)<\/strong>:  The hover function helps to move things around.<\/li>\n<li>\n<strong>!ref.current<\/strong>:  Check whether the current attribute doesn\u2019t exist at the defined variable ref from the <code>useRef<\/code> hook. We stop the function by passing the return keyword.<\/li>\n<li>Next is to check whether the <code>dragIndex<\/code> and <code>hoverIndex<\/code> are equal, meaning the item moved or dragged should do nothing if the item is not moved up and down the list of items with the return keyword stopping the function from firing.<\/li>\n<li>\n<strong>hoverBoundingRect<\/strong>: It determines the rectangle on screen on the current attribute.<\/li>\n<li>\n<strong>hoverMiddleY<\/strong>: Get the vertical middle.<\/li>\n<li>\n<strong>clientOffset<\/strong>: This variable determines the mouse position.<\/li>\n<li>\n<strong>hoverClientY<\/strong>: It returns the pixels to the top.<\/li>\n<li>Next, we check the <code>dragIndex<\/code>, <code>hoverIndex<\/code>, <code>hoverClientY<\/code>, and <code>hoverMiddleY<\/code> are equal; otherwise, stop the funtion.<\/li>\n<\/ul>\n<h2>Rearrange the Gallery Images with React DnD<\/h2>\n<p>For the tutorial to be complete, we need to be able to move the image from one location to\nanother. Add the following code to the <code>App<\/code> component.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ import<\/span>\n    \n<span class=\"hljs-comment\">\/\/ Card component<\/span>\n    \n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-comment\">\/\/ state<\/span>\n      \n<span class=\"hljs-comment\">\/\/ add this<\/span>\n<span class=\"hljs-keyword\">const<\/span> moveImage = React.useCallback(<span class=\"hljs-function\">(<span class=\"hljs-params\">dragIndex, hoverIndex<\/span>) =&gt;<\/span> {\n    setImages(<span class=\"hljs-function\">(<span class=\"hljs-params\">prevCards<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> clonedCards = &#91;...prevCards];\n    <span class=\"hljs-keyword\">const<\/span> removedItem = clonedCards.splice(dragIndex, <span class=\"hljs-number\">1<\/span>)&#91;<span class=\"hljs-number\">0<\/span>];\n    clonedCards.splice(hoverIndex, <span class=\"hljs-number\">0<\/span>, removedItem);\n    <span class=\"hljs-keyword\">return<\/span> clonedCards;\n});\n}, &#91;]);\n    \n<span class=\"hljs-keyword\">return<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n    {React.Children.toArray(\n      images.map((image, index) =&gt; (\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Card<\/span>\n          <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{image.img}<\/span>\n          <span class=\"hljs-attr\">title<\/span>=<span class=\"hljs-string\">{image.title}<\/span>\n          <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">{image.id}<\/span>\n          <span class=\"hljs-attr\">index<\/span>=<span class=\"hljs-string\">{index}<\/span>\n          <span class=\"hljs-attr\">moveImage<\/span>=<span class=\"hljs-string\">{moveImage}<\/span> \/\/ <span class=\"hljs-attr\">add<\/span> <span class=\"hljs-attr\">this<\/span>\n        \/&gt;<\/span>\n      ))\n    )}\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/span>\n);\n};\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The code above does the following:<\/p>\n<ul>\n<li>We updated the <code>Card<\/code> component with the <code>moveImage<\/code> props and called it in its component.<\/li>\n<li>Using the useCallback hook, we rerender the updated cards by updating them with <code>setImages<\/code>\n<\/li>\n<li>The <code>splice<\/code> method on the <code>moveImage<\/code> variable replaces the previous image and adds the new dragged image in its position.<\/li>\n<\/ul>\n<p>Below is the complete code for the  <code>App.js<\/code> file.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { useDrag, useDrop } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-dnd\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> galleryList <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/data.js\"<\/span>;\n<span class=\"hljs-keyword\">const<\/span> Card = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ src, title, id, index, moveImage }<\/span>) =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> ref = React.useRef(<span class=\"hljs-literal\">null<\/span>);\n  <span class=\"hljs-keyword\">const<\/span> &#91;, drop] = useDrop({\n    <span class=\"hljs-attr\">accept<\/span>: <span class=\"hljs-string\">\"image\"<\/span>,\n    <span class=\"hljs-attr\">hover<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">item, monitor<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-keyword\">if<\/span> (!ref.current) {\n        <span class=\"hljs-keyword\">return<\/span>;\n      }\n      <span class=\"hljs-keyword\">const<\/span> dragIndex = item.index;\n      <span class=\"hljs-keyword\">const<\/span> hoverIndex = index;\n      <span class=\"hljs-keyword\">if<\/span> (dragIndex === hoverIndex) {\n        <span class=\"hljs-keyword\">return<\/span>;\n      }\n      <span class=\"hljs-keyword\">const<\/span> hoverBoundingRect = ref.current?.getBoundingClientRect();\n      <span class=\"hljs-keyword\">const<\/span> hoverMiddleY =\n        (hoverBoundingRect.bottom - hoverBoundingRect.top) \/ <span class=\"hljs-number\">2<\/span>;\n      <span class=\"hljs-keyword\">const<\/span> clientOffset = monitor.getClientOffset();\n      <span class=\"hljs-keyword\">const<\/span> hoverClientY = clientOffset.y - hoverBoundingRect.top;\n      <span class=\"hljs-keyword\">if<\/span> (dragIndex &lt; hoverIndex &amp;&amp; hoverClientY &lt; hoverMiddleY) {\n        <span class=\"hljs-keyword\">return<\/span>;\n      }\n      <span class=\"hljs-keyword\">if<\/span> (dragIndex &gt; hoverIndex &amp;&amp; hoverClientY &gt; hoverMiddleY) {\n        <span class=\"hljs-keyword\">return<\/span>;\n      }\n      moveImage(dragIndex, hoverIndex);\n      item.index = hoverIndex;\n    }\n  });\n  <span class=\"hljs-keyword\">const<\/span> &#91;{ isDragging }, drag] = useDrag({\n    <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">\"image\"<\/span>,\n    <span class=\"hljs-attr\">item<\/span>: <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-keyword\">return<\/span> { id, index };\n    },\n    <span class=\"hljs-attr\">collect<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">monitor<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-keyword\">return<\/span> {\n        <span class=\"hljs-attr\">isDragging<\/span>: monitor.isDragging()\n      };\n    }\n  });\n  <span class=\"hljs-keyword\">const<\/span> opacity = isDragging ? <span class=\"hljs-number\">0<\/span> : <span class=\"hljs-number\">1<\/span>;\n  drag(drop(ref));\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">ref<\/span>=<span class=\"hljs-string\">{ref}<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">opacity<\/span> }} <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"card\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{src}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{title}<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n};\n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> &#91;images, setImages] = React.useState(galleryList);\n  <span class=\"hljs-keyword\">const<\/span> moveImage = React.useCallback(<span class=\"hljs-function\">(<span class=\"hljs-params\">dragIndex, hoverIndex<\/span>) =&gt;<\/span> {\n    setImages(<span class=\"hljs-function\">(<span class=\"hljs-params\">prevCards<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-keyword\">const<\/span> clonedCards = &#91;...prevCards];\n      <span class=\"hljs-keyword\">const<\/span> removedItem = clonedCards.splice(dragIndex, <span class=\"hljs-number\">1<\/span>)&#91;<span class=\"hljs-number\">0<\/span>];\n      clonedCards.splice(hoverIndex, <span class=\"hljs-number\">0<\/span>, removedItem);\n      <span class=\"hljs-keyword\">return<\/span> clonedCards;\n    });\n  }, &#91;]);\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n      {React.Children.toArray(\n        images.map((image, index) =&gt; (\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Card<\/span>\n            <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{image.img}<\/span>\n            <span class=\"hljs-attr\">title<\/span>=<span class=\"hljs-string\">{image.title}<\/span>\n            <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">{image.id}<\/span>\n            <span class=\"hljs-attr\">index<\/span>=<span class=\"hljs-string\">{index}<\/span>\n            <span class=\"hljs-attr\">moveImage<\/span>=<span class=\"hljs-string\">{moveImage}<\/span>\n          \/&gt;<\/span>\n        ))\n      )}\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/span>\n  );\n};\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_7672E199EC7800126C5ECD69774B16791DD8D435B636DB6CD4636935243DBD18_1651153013305_Animation.gif\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1896\" height=\"877\"\/><\/p>\n<h2>Conclusion<\/h2>\n<p>This post discussed how to rearrange gallery images with the drag and drop feature of React DnD.<\/p>\n<h2>Resources<\/h2>\n<p><a href=\"https:\/\/react-dnd.github.io\/react-dnd\/docs\/tutorial\">React Dnd<\/a><\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28335,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,370,177,246,371],"class_list":["post-28334","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-image","tag-javascript","tag-react","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How to Rearrange Gallery Images Using React DnD<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Rearrange Gallery Images Using React DnD\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-04-28T14:40:08+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-15T20:02:36+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924791\/Web_Assets\/blog\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885.png?_i=AA\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"How to Rearrange Gallery Images Using React DnD\",\"datePublished\":\"2022-04-28T14:40:08+00:00\",\"dateModified\":\"2025-02-15T20:02:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/\"},\"wordCount\":8,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924791\/Web_Assets\/blog\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885.png?_i=AA\",\"keywords\":[\"Guest Post\",\"Image\",\"Javascript\",\"React\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/\",\"name\":\"How to Rearrange Gallery Images Using React DnD\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924791\/Web_Assets\/blog\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885.png?_i=AA\",\"datePublished\":\"2022-04-28T14:40:08+00:00\",\"dateModified\":\"2025-02-15T20:02:36+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924791\/Web_Assets\/blog\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924791\/Web_Assets\/blog\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885.png?_i=AA\",\"width\":1903,\"height\":883},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Rearrange Gallery Images Using React DnD\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to Rearrange Gallery Images Using React DnD","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/","og_locale":"en_US","og_type":"article","og_title":"How to Rearrange Gallery Images Using React DnD","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-04-28T14:40:08+00:00","article_modified_time":"2025-02-15T20:02:36+00:00","twitter_card":"summary_large_image","twitter_image":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924791\/Web_Assets\/blog\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885.png?_i=AA","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/"},"author":{"name":"","@id":""},"headline":"How to Rearrange Gallery Images Using React DnD","datePublished":"2022-04-28T14:40:08+00:00","dateModified":"2025-02-15T20:02:36+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/"},"wordCount":8,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924791\/Web_Assets\/blog\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885.png?_i=AA","keywords":["Guest Post","Image","Javascript","React","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/","name":"How to Rearrange Gallery Images Using React DnD","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924791\/Web_Assets\/blog\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885.png?_i=AA","datePublished":"2022-04-28T14:40:08+00:00","dateModified":"2025-02-15T20:02:36+00:00","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924791\/Web_Assets\/blog\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924791\/Web_Assets\/blog\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885.png?_i=AA","width":1903,"height":883},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-rearrange-gallery-images-using-react-dnd\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to Rearrange Gallery Images Using React DnD"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924791\/Web_Assets\/blog\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885\/efbea2dae52731cf318583f763f7e9d5d91dc8eb-1903x883-1_2833522885.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28334","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=28334"}],"version-history":[{"count":1,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28334\/revisions"}],"predecessor-version":[{"id":36808,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28334\/revisions\/36808"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28335"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28334"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28334"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}