Closed fahadashiq12 closed 2 years ago
I'm using it with React 18 without troubles.
I'm using it with React 18 without troubles.
I am reading some articles that react-dnd-beautiful has become obsolete after react 16 version, well react-dnd can still be use in react 18?
I am have installed it using -peer-legacy command while installing through npm which is reccommended for legacy support feature in latest version of React - any other alternative to it?
It works with React 18 but not inside the StrictMode
wrapper.
It works with React 18 but not inside the
StrictMode
wrapper.
Thanks, removing StrictMode
Wrapper worked for me. I was getting Unable to find draggable with id: 2
errors. I am not sure what was causing this. But thanks again for the help.
It works with React 18 but not inside the
StrictMode
wrapper.
Same issue as above. It was not finding the draggable with id. After removing the StrictMode wrapper it working perfectly. Thanks! (I'm using react 18 as well)
Is there an issue registered for not working within Strict Mode? Probably related to the double firing of useEffect.
Can someone explain what is #strictmode?
"StrictMode is a tool for highlighting potential problems in an application."
https://reactjs.org/docs/strict-mode.html https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-strict-mode
On Thu, May 19, 2022 at 3:03 PM Fahad Ashiq ⚡ @.***> wrote:
Can someone explained what is #StrictMode?
— Reply to this email directly, view it on GitHub https://github.com/atlassian/react-beautiful-dnd/issues/2399#issuecomment-1131662225, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABT6D2ADCCX3GZTIM4YPLDVKY32TANCNFSM5UH3T6AA . You are receiving this because you commented.Message ID: @.***>
i am getting draggable id issue without using it in strict mode
https://codesandbox.io/s/staging-field-ej6ghv?file=/src/App.js
Just be aware that this new bug with React 18 has to do with concurrent rendering and how 'react-beautiful-dnd' registers their droppables inside the hook. The library is doing it inside a useLayoutEffect with a dependency array, so it will fire on the first componentDidMount, but not afterwards when the component gets remounted, which is how React 18 behaves in StrictMode.
One way I found to fix the issue with react-beautiful-dnd and React 18 in StrictMode was to render the Droppable
elements after an animation frame... something like this:
const DropComponent = () => {
const [ enabled, setEnabled ] = React.useState(false);
React.useEffect(() => {
const animation = requestAnimationFrame(() => setEnabled(true));
return () => {
cancelAnimationFrame(animation);
setEnabled(false);
};
}, []);
if (!enabled) {
return null;
}
return (
<Droppable droppableId={...}>
{ .... }
</Droppable>
);
}
In my case, it seemed to have fixed the timing issue when register.clean
was getting called after the Droppable elements were registered.
One way I found to fix the issue with react-beautiful-dnd and React 18 in StrictMode was to render the
Droppable
elements after an animation frame... something like this:
Thanks a lot. This seems to work for me.
If anyone needs a TypeScript version:
import { useEffect, useState } from "react";
import { Droppable, DroppableProps } from "react-beautiful-dnd";
export const StrictModeDroppable = ({ children, ...props }: DroppableProps) => {
const [enabled, setEnabled] = useState(false);
useEffect(() => {
const animation = requestAnimationFrame(() => setEnabled(true));
return () => {
cancelAnimationFrame(animation);
setEnabled(false);
};
}, []);
if (!enabled) {
return null;
}
return <Droppable {...props}>{children}</Droppable>;
};
Thanks guys, I was also face the same issue then, I found this page and removed 'stricktMode' and now it's working fine for me. You make my day.
Hello! I released a fork of this project which natively supports React 18 and strict mode, called @hello-pangea/dnd
npm install @hello-pangea/dnd
react-beautiful-dnd
with @hello-pangea/dnd
It works with React 18 but not inside the
StrictMode
wrapper.Same issue as above. It was not finding the draggable with id. After removing the StrictMode wrapper it working perfectly. Thanks! (I'm using react 18 as well)
yes I ts worked for me, thank u so much
Hey folks, I've updated the peerdep in the latest version.
It works with React 18 but https://github.com/atlassian/react-beautiful-dnd/issues/2350 inside the StrictMode wrapper.
This is still correct
Will close this issue for now, let's continue the discussion about strict mode support here: https://github.com/atlassian/react-beautiful-dnd/issues/2350
It works with React 18 but not inside the
StrictMode
wrapper.
Thank you very much @gavinorland, I've been going crazy for two or three days.
Thanks a lot its works for me without turning off StrictMode
One way I found to fix the issue with react-beautiful-dnd and React 18 in StrictMode was to render the
Droppable
elements after an animation frame... something like this:Thanks a lot. This seems to work for me.
If anyone needs a TypeScript version:
import { useEffect, useState } from "react"; import { Droppable, DroppableProps } from "react-beautiful-dnd"; export const StrictModeDroppable = ({ children, ...props }: DroppableProps) => { const [enabled, setEnabled] = useState(false); useEffect(() => { const animation = requestAnimationFrame(() => setEnabled(true)); return () => { cancelAnimationFrame(animation); setEnabled(false); }; }, []); if (!enabled) { return null; } return <Droppable {...props}>{children}</Droppable>; };
Works perfect!!! Thank you all!
For React 18, the trick is just to make sure that component it's mounted when rendering 'Droppable'.
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, []);
return isMounted ? <Droppable {...props}>{children}</Droppable> : null;
You don't need to create a new component just for this...
@florin-holhos's answer worked for awhile until I added more code and had more than one useEffect
running in my component. This caused the same issue to return.
This completely fixed the issue. Here is a hook version of that:
import { useEffect, useState } from 'react';
export const useDragAndDropWithStrictMode = () => {
const [isDragAndDropEnabled, setIsDragAndDropEnabled] = useState(false);
useEffect(() => {
const animation = requestAnimationFrame(() => setIsDragAndDropEnabled(true));
return () => {
cancelAnimationFrame(animation);
setIsDragAndDropEnabled(false);
};
}, []);
return { isDragAndDropEnabled };
};
Then use like so:
return (isDragAndDropEnabled ? <Droppable ...>...</Droppable> : null);
I have bunch of problems in typescript, using this code
@DawidBugajski ,
I'd imagine it is because of the JSX code. Probably need to change the file extension to .tsx
instead of .ts
worked great!
that is, for reasons i could not resolve, nested lists briefly disappears on state update, so the whole list kinda jumps up & down at that moment; feels glitchy
It will work with React 18 with 2 ways
1) remove strictmode 2) dont use createRoot use ReactDOM.render
It will work with React 18 with 2 ways
1) remove strictmode
2) dont use createRoot use ReactDOM.render
Thankyou for answering ✅
Thanks soooo much! The best solution in my mind!!
For React 18, the trick is just to make sure that component it's mounted when rendering 'Droppable'.
const [isMounted, setIsMounted] = useState(false); useEffect(() => { setIsMounted(true); }, []); return isMounted ? <Droppable {...props}>{children}</Droppable> : null;
You don't need to create a new component just for this...
Until today the @Meligy answer saved my life (well some hours of my life)
One way I found to fix the issue with react-beautiful-dnd and React 18 in StrictMode was to render the
Droppable
elements after an animation frame... something like this:Thanks a lot. This seems to work for me.
If anyone needs a TypeScript version:
import { useEffect, useState } from "react"; import { Droppable, DroppableProps } from "react-beautiful-dnd"; export const StrictModeDroppable = ({ children, ...props }: DroppableProps) => { const [enabled, setEnabled] = useState(false); useEffect(() => { const animation = requestAnimationFrame(() => setEnabled(true)); return () => { cancelAnimationFrame(animation); setEnabled(false); }; }, []); if (!enabled) { return null; } return <Droppable {...props}>{children}</Droppable>; };
Thank you very much
I was using the "hack" with an animation frame described above https://github.com/atlassian/react-beautiful-dnd/issues/2399#issuecomment-1175638194 but found a problem in my app.
The initial render is null
as expected by that code, which leads to a flicker:
useEffect
& animationFrame
runs I render the children
This was problematic for my app and the user experience so I ended up modifying the code to ONLY have this "hack" in development. We don't need it in productions since the <React.StrictMode>
has no effect there:
NOTE: I'm using Vite that's why I have the
import.meta
special object. A similar approach using "native" props would beprocess.env.NODE_ENV
import { useEffect, useState } from "react";
import { Droppable, DroppableProps } from "react-beautiful-dnd";
export const StrictModeDroppable = ({ children, ...props }: DroppableProps) => {
const [enabled, setEnabled] = useState(import.meta.env.MODE === "production");
useEffect(() => {
const animation = requestAnimationFrame(() => setEnabled(true));
return () => {
cancelAnimationFrame(animation);
setEnabled(false);
};
}, []);
if (!enabled) {
return null;
}
return <Droppable {...props}>{children}</Droppable>;
};
One way I found to fix the issue with react-beautiful-dnd and React 18 in StrictMode was to render the
Droppable
elements after an animation frame... something like this:Thanks a lot. This seems to work for me.
If anyone needs a TypeScript version:
import { useEffect, useState } from "react"; import { Droppable, DroppableProps } from "react-beautiful-dnd"; export const StrictModeDroppable = ({ children, ...props }: DroppableProps) => { const [enabled, setEnabled] = useState(false); useEffect(() => { const animation = requestAnimationFrame(() => setEnabled(true)); return () => { cancelAnimationFrame(animation); setEnabled(false); }; }, []); if (!enabled) { return null; } return <Droppable {...props}>{children}</Droppable>; };
This worked like a charm. If anyone needs unit tests, this worked for me:
import { renderWithProviders } from "@/utils/testUtils";
import { act, screen } from "@testing-library/react";
import { DragDropContext } from "react-beautiful-dnd";
import { StrictModeDroppable } from "./StrictModeDroppable";
describe("StrictModeDroppable", () => {
let originalRequestAnimationFrame: (callback: FrameRequestCallback) => number;
// Mocking requestAnimationFrame
beforeAll(() => {
originalRequestAnimationFrame = window.requestAnimationFrame;
jest.spyOn(window, "requestAnimationFrame").mockImplementation((cb) => {
cb(0);
return 0;
});
});
afterAll(() => {
// Restore the original requestAnimationFrame function
window.requestAnimationFrame = originalRequestAnimationFrame;
});
it("renders Droppable when enabled", () => {
act(() => {
renderWithProviders(
<DragDropContext onDragEnd={jest.fn()}>
<StrictModeDroppable droppableId={"items"}>
{(provided) => (
<div
data-testid="child-component"
ref={provided.innerRef}
{...provided.droppableProps}
>
Child Component
</div>
)}
</StrictModeDroppable>
</DragDropContext>
);
});
const droppableComponent = screen.getByTestId("child-component");
expect(droppableComponent).toBeInTheDocument();
});
it("does not render Droppable when not enabled", () => {
jest.useFakeTimers();
act(() => {
renderWithProviders(
<StrictModeDroppable
droppableId={"items"}
data-testid="strict-mode-droppable"
>
{(provided) => <div>Child Component</div>}
</StrictModeDroppable>
);
// Fast-forward time to trigger useEffect
jest.runAllTimers();
});
const droppableComponent = screen.queryByTestId("strict-mode-droppable");
expect(droppableComponent).toBeNull();
});
});
It works with React 18 but not inside the
StrictMode
wrapper.
It works with React 18
Dont Revome strict mode. just use createRoot, in index.js. I have achieved multiple drag-drop and some advance functionality with this. Removing strict mode was a bad idea just change the rendering way. we will use old way. This will not effect performance.
My console screen has following message:
react-beautiful-dndDroppable setup issue [droppableId: "todo"]:
DroppableProvided > placeholder could not be found.Please be sure to add the {provided.placeholder}
React Node as a child of your Droppable.More information: https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/api/droppable.md👷
This is a development only message. It will be removed in production builds.