I have a problem with event bubbling. I'm using React DnD Beautiful to sort a vertical list. I have a list of collections and within each collection there is a nested list of services.
I can either drag and drop collections to sort them vertically or drag and drop services only within a correspondent collection to sort them as well.
When I drag collections, everything is working properly. But when I try to drag services, sometimes instead of grabbing a service, I grab a whole collection. It happens due to an event bubbling. Usually, I would solve the problem with e.stopPropagation(), but it seems not to work.
React DnD Beautiful uses {...provided.dragHandleProps} where they, for instance, handle onDragStart. I tried to customize it, but it didn't work. I wonder, whether I'm just customizing it wrong?
Beneath is a pseudocode.
COLLECTION LIST
function SortableCollectionsList() {
const styles = useStyles();
const {sortedCollections, onDragEnd} = useSortedCollections()
return (
<div className={"collectionListWrapper"}>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="droppable" direction="vertical">
{(provided, snapshot) => (
// List of all collections
<List
ref={provided.innerRef}
{...provided.droppableProps}
aria-labelledby="nested-list-subheader"
subheader={
<ListSubheader component="div" id="nested-list-subheader">
Drag and drop collections and services
</ListSubheader>
}
className={styles.root}
>
{sortedCollections
.map(({id, name, showName, logo, services: serviceIds}, index) =>
<Draggable key={id} draggableId={id} index={index}>
{(provided, snapshot) => (
<>
{/*One collection containing a list of services*/}
<ListItem key={id}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
onDragStart={(e) => {
e.stopPropagation(),
provided.dragHandleProps.onDragStart(e),
console.log("collections stop propagation")
}}
className={styles.collection}
>
{/*List of services within one collection*/}
<SortableServicesList {...{
serviceIds,
collectionId: id,
title: name
}}/>
</ListItem>
</>
)}
</Draggable>
)}
{provided.placeholder}
</List>
)}
</Droppable>
</DragDropContext>
</div>
)
}
SERVICES WITHIN EACH COLLECTION
function SortableServicesList({serviceIds, collectionId, title}) {
const {sortedServices, onDragEnd} = useSortedServices(serviceIds, collectionId)
const classes = useStyles();
const [open, setOpen] = React.useState(true);
const handleClick = () => {
setOpen(!open);
};
return (
// A collection LIST (one list) of services
<List
component="nav"
aria-labelledby="nested-list-subheader"
className={classes.root}
>
<ListItem button onClick={handleClick}>
<DragIndicatorIcon fontSize="small"/>
<ListItemText primary={title}/>
{open ? <ExpandLess/> : <ExpandMore/>}
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="droppable" direction="vertical">
{(provided, snapshot) => (
// LIST AS A DROPPABLE CONTAINER FOR THE SERVICES
<List ref={provided.innerRef}
style={getContainerStyle(snapshot.isDraggingOver)}
{...provided.droppableProps}
className="collectionItems"
component="div"
disablePadding
>
{sortedServices
.map(({id, name}, index) =>
// A LIST ITEM AS A DRAGGABLE SERVICE
<Draggable key={id} draggableId={id} index={index}>
{(provided, snapshot) => (
<>
<ListItem button
key={id}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
onDragStart={(e) => {
e.stopPropagation(),
provided.dragHandleProps.onDragStart(e),
console.log("services stop propagation")
}}
style={getServiceCardStyle(
snapshot.isDragging,
provided.draggableProps.style,
)}
className={classes.nested}
>
<DragIndicatorIcon fontSize="small"/>
<ListItemText primary={name}/>
</ListItem>
</>
)}
</Draggable>
)}
{provided.placeholder}
</List>
)}
</Droppable>
</DragDropContext>
</Collapse>
</List>
)
}
As you can observe, I'm also confused where should I define my custom event. For now, I just did the same for both collections and services, namely this:
onDragStart={(e) => {
e.stopPropagation(),
provided.dragHandleProps.onDragStart(e),
console.log("services stop propagation")
}}
And also it doesn't console.log() anything.
Ty for your help. I'm actually a beginner and it is very confusing for me, even if it is easy.