Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dragging not working using SSR after refresh #1854

Open
tettoffensive opened this issue Jun 2, 2020 · 28 comments
Open

Dragging not working using SSR after refresh #1854

tettoffensive opened this issue Jun 2, 2020 · 28 comments

Comments

@tettoffensive
Copy link

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.

#1775 (comment)

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)

@dhruvbhatia7
Copy link

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)

@daveteu
Copy link

daveteu commented Jul 1, 2020

also using nextJS facing this. but I did not use SSR

image

Can be easily reproduce with any sample codes.

Apparently linked to this #1883 . It can be used after npm run build but not when in hot reload environment

@denieler
Copy link

Guys, try to make this in _document.js:

import { resetServerContext } from 'react-beautiful-dnd'
...
static getInitialProps({ renderPage }) {
    resetServerContext()
}
...
render () { ...

@vprtwn
Copy link

vprtwn commented Aug 2, 2020

Guys, try to make this in _document.js:


import { resetServerContext } from 'react-beautiful-dnd'

...

static getInitialProps({ renderPage }) {

    resetServerContext()

}

...

render () { ...

This worked for me

@MacGyver98
Copy link

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...

image

May be do you have any clue?

@MacGyver98
Copy link

MacGyver98 commented Sep 14, 2020

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)

skqksh added a commit to skqksh/next-kanban that referenced this issue Nov 12, 2020
@dimitrisraptis96
Copy link

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>

@hopetambala
Copy link

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

@lopezjurip
Copy link

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: {} };
};

@ivorpad
Copy link

ivorpad commented Mar 3, 2021

Another solution:

const [isBrowser, setIsBrowser] = useState(false);

useEffect(() => {
  setCanRender(process.browser);
}, [])

function Home() {
  return(
   <>
    {isBrowser ? <DragDropContext> { /* all rbd code */ } </DragDropContext> : null}
   </>
  )
}

@IKrehan
Copy link

IKrehan commented Apr 4, 2021

This worked for me:
image

@medihack
Copy link

medihack commented May 21, 2021

@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.

@medihack
Copy link

medihack commented May 21, 2021

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.

@uncvrd
Copy link

uncvrd commented Jul 7, 2021

The react-no-ssr component worked for me, but I would like to know why resetServerContext doesn't work as expected

@trinhphuocbinh1993
Copy link

trinhphuocbinh1993 commented Jul 30, 2021

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/

@medihack
Copy link

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).

@dhruvindsd-dev
Copy link

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.

@sharva
Copy link

sharva commented Oct 3, 2021

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},
);

@WaleedAmer
Copy link

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 :)

@gx2475
Copy link

gx2475 commented Oct 30, 2021

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?

@codelover2k
Copy link

codelover2k commented Nov 14, 2021

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.

@asenseofpradhyu
Copy link

Any update on this ????

@planktonrobo
Copy link

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!

@nirajpdn
Copy link

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.

@tettoffensive
Copy link
Author

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 },
);

@masterkain
Copy link

somebody made it work with next13 + app directory? mixed server and client components with 'use client'; directive

@shrix1
Copy link

shrix1 commented Jun 16, 2023

What about Nextjs 13.4.4 + App Directory . Im having this Issue . please help

@SemX74
Copy link

SemX74 commented Sep 23, 2023

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests