react-beautiful-dnd icon indicating copy to clipboard operation
react-beautiful-dnd copied to clipboard

Invariant failed: Draggable[id: 2]: Unable to find drag handle on SSR, with Next JS

Open aliburhankeskin opened this issue 4 years ago • 14 comments

On every click and every page refresh , output console

error

_document.js

import { ServerStyleSheets } from '@material-ui/core/styles'; import { resetServerContext } from 'react-beautiful-dnd';

`

  MyDocument.getInitialProps = async (ctx) => {
      const sheets = new ServerStyleSheets();
      const originalRenderPage = ctx.renderPage;
      ctx.renderPage = () => originalRenderPage({
        enhanceApp: (App) => (props) => {
          resetServerContext();
          return sheets.collect(<App {...props} />);
        },
      });

` Can you please fix this error.

aliburhankeskin avatar Feb 14 '21 10:02 aliburhankeskin

I'm also getting faceing this issue. Any recommentation?

mtahagocer avatar Feb 14 '21 10:02 mtahagocer

I'm facing the exact same issue even after calling resetServerContext() correctly.

//__document.js
import Document from "next/document";
import { ServerStyleSheet } from "styled-components";
import { resetServerContext } from "react-beautiful-dnd";

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
        
      resetServerContext();
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }
}

// _app.js
import '../styles/globals.css'
import { ChakraProvider } from "@chakra-ui/react";
import { DragDropContext, resetServerContext } from "react-beautiful-dnd";

export default function MyApp({ Component, pageProps }) {
  return (
    <ChakraProvider>
      <Component {...pageProps} />
    </ChakraProvider>
  );
}

export const getServerSideProps = async ({ query }) => {
    resetServerContext();
    return {props: { data : []}}
}

ivorpad avatar Mar 02 '21 23:03 ivorpad

I'm facing the same issue using v13, but without using SSR. Trying to create a minimal repro on codesandbox but no luck yet.

heyimalex avatar Mar 16 '21 03:03 heyimalex

dupe of #1854

heyimalex avatar Mar 16 '21 04:03 heyimalex

Any luck so far with this? I haven't been able to get this to work with Nextjs and Chakra-ui

pjtf93 avatar May 03 '21 00:05 pjtf93

@pjtf93 I solved it by returning the DragDropContext only if process.browser is true.

{ process.browser ? <DragDropContext onDragEnd={onDragEnd}> ... </DragDropContext> : null }

ivorpad avatar May 04 '21 15:05 ivorpad

Only rendering it in the browser is IMHO an ugly workaround. We should fix react-beautiful-dnd for supporting SSR on latest Next.js. It is just a matter of providing the correct IDs. Maybe there should be a way to optionally set them manually instead of auto generating them.

medihack avatar May 21 '21 06:05 medihack

@medihack Is not ugly if you don't care about the DnD being SSR'd. What's wrong with it?

ivorpad avatar May 21 '21 09:05 ivorpad

@ivorpad In my opinion SSR should work fully as it is officially supported by this library (and I guess it is not very difficult to fix). But I am happy that your solution works for you.

medihack avatar May 21 '21 11:05 medihack

Solved

  • Note : I used NextJS for React I was getting the same error in development and production as well.

It occurs because DOM and window is not loaded before that our component gets loaded.

Here's a solution :

  • Make Sure your window object is ready before your component loads up.
  • Here's code that I have implemented
import dynamic from "next/dynamic";
const Column = dynamic(import("./Column/Column"));
function ScrumBoard() {
    const [winReady, setwinReady] = useState(false);
    useEffect(() => {
        setwinReady(true);
    }, []);
    return (
        <div className="pl-4 pr-4 pt-3">
           ` <h5>Frontend Board</h5>`
            {winReady ? <Column /> : null}
        </div>
    );
}
export default ScrumBoard;

saurabhburade avatar Jan 27 '22 12:01 saurabhburade

@saurabhburade Unfortunately, with your method you lose again the SSR advantages

1-Felix avatar Apr 14 '22 20:04 1-Felix

resetServerContext(); seems to work if reactStrictMode is disabled in next.config.js. But that's not really a solution.

mactanner avatar Jul 18 '22 16:07 mactanner

The { ...provided.dragHandleProps} is missing from the draggable component.

I haven't found any tutorial that includes it.

After days of debugging I found this source code on Github

Screenshot_20220801-090624

I know something is wrong, some people includes it, some do not and it works as expected.

I will like to learn more about this.

mustaphatg avatar Aug 01 '22 08:08 mustaphatg