react-beautiful-dnd
react-beautiful-dnd copied to clipboard
Dragging not working using SSR after refresh
I'm experiencing the issues mentioned in this issue. For some reason, it was closed, even though the issue isn't resolved. However, unlike the reporter in this issue, I am using the suggested _document.js
API.
https://github.com/atlassian/react-beautiful-dnd/issues/1775#issuecomment-636077095
Expected behavior
react-beautiful-dnd should run without warnings and errors when using SSR with next.js production AND dev. I should be able to always pick up draggable items.
Actual behavior
Receiving the following errors when trying to run react-beautiful-dnd with next.js:
react-beautiful-dnd
Unable to find any drag handles in the context "0"
π·β This is a development only message. It will be removed in production builds. react-beautiful-dnd.esm.js:39 react-beautiful-dnd
A setup problem was encountered.
Invariant failed: Draggable[id: id-0}]: Unable to find drag handle
π·β This is a development only message. It will be removed in production builds. react-beautiful-dnd.esm.js:39 react-beautiful-dnd
Unable to find any drag handles in the context "0"
π·β This is a development only message. It will be removed in production builds.
Which according to other issues should resolve the problem with the client, server id mismatches when using SSR. But it's not resolved for me sadly.
The issue appears to be most reproduceable, by refreshing the page after initial load in development mode.
Steps to reproduce
Install the next.js, react-beautiful-react-dnd Follow this tutorial: https://egghead.io/courses/beautiful-and-accessible-drag-and-drop-with-react-beautiful-dnd
In this tutorial the attribute innerRef is being used. Don't use it. Instead use the ref attribute!
What version of react-beautiful-dnd
and react
are you running?
I'm using the following dependencies (listed in my package.json file):
"react": "^16.13.1",
"react-beautiful-dnd": "^13.0.0",
Next.js v9.4.0
What browser are you using?
Chrome Version 83.0.4103.61 (Official Build) (64-bit) Firefox 76.0.1 (64-bit)
I'm facing this exact issue. I'm also using nextjs and SSR
react-beautiful-dndA setup problem was encountered.> Invariant failed: Draggable[id: ostKJgjkAzaeOBWowkz9]: Unable to find drag handleπ·β This is a development only message. It will be removed in production builds. at Draggable (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:92012:65) at ConnectFunction (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:108095:75) at PrivateDraggable (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:92364:26) at PublicDraggable (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:92374:32) at div at Droppable (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:92386:76) at ConnectFunction (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:108095:75) at Provider (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:107808:20) at App (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:90983:25) at ErrorBoundary (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:84248:35) at DragDropContext (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:91112:19) at div at div at http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:95916:23 at div at div at http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:93645:23 at div at http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:94302:23 at div at http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:98297:23 at div at TasksInfo (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:1040:80) at div at div at http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:94302:23 at div at http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:98297:23 at div at http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:94525:23 at div at Dashboard (http://localhost:3000/_next/static/development/pages/dashboard.js?ts=1592266231892:112708:22) at MyApp (http://localhost:3000/_next/static/development/pages/_app.js?ts=1592266231892:4225:24) at Container (http://localhost:3000/_next/static/runtime/main.js?ts=1592266231892:2829:5) at AppContainer (http://localhost:3000/_next/static/runtime/main.js?ts=1592266231892:3245:24)
also using nextJS facing this. but I did not use SSR
Can be easily reproduce with any sample codes.
Apparently linked to this https://github.com/atlassian/react-beautiful-dnd/issues/1883 . It can be used after npm run build but not when in hot reload environment
Guys, try to make this in _document.js
:
import { resetServerContext } from 'react-beautiful-dnd'
...
static getInitialProps({ renderPage }) {
resetServerContext()
}
...
render () { ...
Guys, try to make this in
_document.js
:import { resetServerContext } from 'react-beautiful-dnd' ... static getInitialProps({ renderPage }) { resetServerContext() } ... render () { ...
This worked for me
Guys, try to make this in
_document.js
:import { resetServerContext } from 'react-beautiful-dnd' ... static getInitialProps({ renderPage }) { resetServerContext() } ... render () { ...
Something change, now the bug is another...
May be do you have any clue?
Guys, try to make this in
_document.js
:import { resetServerContext } from 'react-beautiful-dnd' ... static getInitialProps({ renderPage }) { resetServerContext() } ... render () { ...
Sorry, my mistake. It works !!! I was using Draggable in wrong way... Gracias compadre! (as we say in my country)
Another solution was to use the react-no-ssr library. Just wrap the whole DND component with <NoSSR>
.
<NoSSR>
... // react-beautiful-dnd code inside
</NoSSR>
Another solution was to use the react-no-ssr library. Just wrap the whole DND component with
<NoSSR>
.<NoSSR> ... // react-beautiful-dnd code inside </NoSSR>
This worked! Thanks
getInitialProps
is deprecated, I would recommend using getServerSideProps
to fix this issue.
Here is how to do it with Typescript:
import { GetServerSideProps } from "next";
import { resetServerContext } from "react-beautiful-dnd";
export const getServerSideProps: GetServerSideProps = async (context) => {
resetServerContext();
return { props: {} };
};
Another solution:
const [isBrowser, setIsBrowser] = useState(false);
useEffect(() => {
setCanRender(process.browser);
}, [])
function Home() {
return(
<>
{isBrowser ? <DragDropContext> { /* all rbd code */ } </DragDropContext> : null}
</>
)
}
This worked for me:
@IKrehan solution is not really correct as resetServerContext
should run on the server. But I guess it works on the client if you only use one DragDropContext
. The problem is that with up-to-date Next.js (v10.2.x) it does not work anymore when resetServerContext
is called in getInitialProps
or getServerSideProps
(react-dom.development.js:66 Warning: Prop
data-rbd-draggable-context-id did not match. Server: "0" Client: "1"
). I will investigate a bit further.
After some investigation and looking at the code it seems the root of the problem is more the client-side than the server-side. resetServerContext
resets the context id correctly each time (that's why Server: "0"
is logged). But in strict mode (I have it enabled as recommended by the Next.js team the client code is rendered twice. This is why the id ends up as 1 (Client: "1"
) instead of 0 (even I only have one DragDropContext
. Can anyone confirm that React strict mode is enabled in his setup, too?
A possible workaround (just tested quickly) is to directly call resetServerContext
in the render method of every page component which uses react-beautiful-dnd
. That way the context id is reset on the server and client and always begins with 0. Not sure if there are any drawbacks.
The react-no-ssr
component worked for me, but I would like to know why resetServerContext
doesn't work as expected
If you guys want to use react-beautiful-dnd with Next.js, this is my solution, i just make a component contain dnd not work with SSR of Next and it's work for me.
// your route (like dashboard/index.js)
import dynamic from 'next/dynamic';
const Your_Component_Name = dynamic(() => import('your_patch_of_component'), {
ssr: false,
});
export default function App() {
return (
<Your_Component_Name />
)
}
I done my dnd followed by this tutorial: https://www.freecodecamp.org/news/how-to-add-drag-and-drop-in-react-with-react-beautiful-dnd/
Also if you don't need HTML5 DND support then dnd-kit is a very good other solution with Next.js support I am quite happy with (very actively developed).
If you guys want to use react-beautiful-dnd with Next.js, this is my solution, i just make a component contain dnd not work with SSR of Next and it's work for me.
// your route (like dashboard/index.js) import dynamic from 'next/dynamic'; const Your_Component_Name = dynamic(() => import('your_patch_of_component'), { ssr: false, }); export default function App() { return ( <Your_Component_Name /> ) }
I done my dnd followed by this tutorial: https://www.freecodecamp.org/news/how-to-add-drag-and-drop-in-react-with-react-beautiful-dnd/
This works perfectly, thanks for the solution.
If anyone still looking for SSR NextJS solution, following way of importing worked
import dynamic from 'next/dynamic';
const DragDropContext = dynamic(
() =>
import('react-beautiful-dnd').then(mod => {
return mod.DragDropContext;
}),
{ssr: false},
);
const Droppable = dynamic(
() =>
import('react-beautiful-dnd').then(mod => {
return mod.Droppable;
}),
{ssr: false},
);
const Draggable = dynamic(
() =>
import('react-beautiful-dnd').then(mod => {
return mod.Draggable;
}),
{ssr: false},
);
If anyone still looking for SSR NextJS solution, following way of importing worked
import dynamic from 'next/dynamic'; const DragDropContext = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.DragDropContext; }), {ssr: false}, ); const Droppable = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.Droppable; }), {ssr: false}, ); const Draggable = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.Draggable; }), {ssr: false}, );
Thanks so much, this worked for me instantly :)
Guys, try to make this in
_document.js
:import { resetServerContext } from 'react-beautiful-dnd' ... static getInitialProps({ renderPage }) { resetServerContext() } ... render () { ...
so do I create _document.js and then copy this code or what?
getInitialProps is obsolete and should not be used, use getServerSideProps instead.
resetServerContext() does not work in many cases. There is still no official solution.
Would be great to have the SSR logic inside DragDropContext.
Any update on this ????
If anyone still looking for SSR NextJS solution, following way of importing worked
import dynamic from 'next/dynamic'; const DragDropContext = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.DragDropContext; }), {ssr: false}, ); const Droppable = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.Droppable; }), {ssr: false}, ); const Draggable = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.Draggable; }), {ssr: false}, );
Thanks so much, this worked for me instantly :)
This worked well for me!
If anyone still looking for SSR NextJS solution, following way of importing worked
import dynamic from 'next/dynamic'; const DragDropContext = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.DragDropContext; }), {ssr: false}, ); const Droppable = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.Droppable; }), {ssr: false}, ); const Draggable = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.Draggable; }), {ssr: false}, );
Thank you so much.
If anyone still looking for SSR NextJS solution, following way of importing worked
import dynamic from 'next/dynamic'; const DragDropContext = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.DragDropContext; }), {ssr: false}, ); const Droppable = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.Droppable; }), {ssr: false}, ); const Draggable = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.Draggable; }), {ssr: false}, );
If anyone, like me, is using Typescript and getting errors with the above try this:
import dynamic from 'next/dynamic';
const DragDropContext = dynamic(
async () => {
const mod = await import('react-beautiful-dnd');
return mod.DragDropContext;
},
{ ssr: false },
);
const Droppable = dynamic(
async () => {
const mod = await import('react-beautiful-dnd');
return mod.Droppable;
},
{ ssr: false },
);
const Draggable = dynamic(
async () => {
const mod = await import('react-beautiful-dnd');
return mod.Draggable;
},
{ ssr: false },
);
somebody made it work with next13 + app directory? mixed server and client components with 'use client';
directive
What about Nextjs 13.4.4 + App Directory . Im having this Issue . please help
If anyone still looking for SSR NextJS solution, following way of importing worked
import dynamic from 'next/dynamic'; const DragDropContext = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.DragDropContext; }), {ssr: false}, ); const Droppable = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.Droppable; }), {ssr: false}, ); const Draggable = dynamic( () => import('react-beautiful-dnd').then(mod => { return mod.Draggable; }), {ssr: false}, );
thx!