Reputation: 2616
I have this javascript draggable tabs component, it is a copy from another question here: mui-tablist with react beautiful dnd not auto scrolling on drag and it has a codesandbox
My aim is to migrate to typescript and eventually create something similar to the following mockup.
Migrating to typescript: I have taken the above question/answer and merged them together as best I can
import React from 'react';
import TabContext from "@mui/lab/TabContext";
import TabPanel from "@mui/lab/TabPanel";
import { DragDropContext, Droppable, DropResult } from "react-beautiful-dnd";
import { Draggable } from "react-beautiful-dnd";
import { Stack, styled, Tab, Tabs } from "@mui/material";
interface DraggableTabProps {
label: string;
value: string;
index: number;
key: number;
child: JSX.Element;
};
const DraggableTab = ( props: DraggableTabProps ) => {
return (
<Draggable
draggableId={`${props.index}`}
index={props.index}
disableInteractiveElementBlocking
>
{(draggableProvided) => (
<div
ref={draggableProvided.innerRef}
{...draggableProvided.draggableProps}
>
{React.cloneElement(props.child, {
...props,
...draggableProvided.dragHandleProps
})}
</div>
)}
</Draggable>
);
}
const StyledTabs = styled(Tabs)();
const StyledTab = styled(Tab)();
export default function DraggableTabComponent() {
const [value, setValue] = React.useState('1');
const handleChange = (event: React.SyntheticEvent, newValue: string) => {
setValue(newValue);
};
const [tabs, setTabs] = React.useState(
[...Array(25)].map((_, index) => ({
id: `tab${index + 1}`,
label: `Tab ${index + 1}`,
value: `${index + 1}`,
content: `Content ${index + 1}`
}))
);
const onDragEnd = (result: DropResult) => {
const newTabs = Array.from(tabs);
const draggedTab = newTabs.splice(result.source.index, 1)[0];
newTabs.splice(result.destination!.index, 0, draggedTab);
setTabs(newTabs);
};
return (
<TabContext value={value}>
<Stack>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="1" direction="horizontal">
{(droppableProvided) => (
<StyledTabs
ref={droppableProvided.innerRef}
{...droppableProvided.droppableProps}
value={value}
onChange={handleChange}
variant="scrollable"
scrollButtons
allowScrollButtonsMobile
>
{tabs.map((tab, index) => {
const child = (
<StyledTab label={tab.label} value={tab.value} key={index} />
);
return (
<DraggableTab
label={tab.label}
value={tab.value}
index={index}
key={index}
child={child}
/>
);
})}
{droppableProvided ? droppableProvided.placeholder : null}
</StyledTabs>
)}
</Droppable>
</DragDropContext>
</Stack>
{tabs.map((tab, index) => (
<TabPanel value={tab.value} key={index}>
{tab.content}
</TabPanel>
))}
</TabContext>
);
}
This displays the tabs and I am able to click each tab and view its content, but I get an error along with each click for the draggable, e.g. on the first tab:
react_devtools_backend.js:4026 react-beautiful-dnd Unable to find draggable with id: 0
Could use some help to fix this up, thanks
Upvotes: 0
Views: 930
Reputation: 197
It's a known issue with react-beautiful-dnd
package, and it occurs only in dev mode and React v18.
Strict mode checks are run in development mode only; they do not impact the production build.
Apparently, to solve it you have to disable strict mode for the part of your application that uses your Tab component which is not the best solution, or just ignore the issue because it is not present in the production mode.
Upvotes: 1