I have an issue using the deleteProyect function, when the client clicks the button, the component does not eliminate the object in the array unless yo click as fast as you can, so it could be something related to useEfect IDK, i hope you can help me, thanks!
ProyectContext.jsx
import React, { useState, createContext, useEffect } from "react";
import { proyects as data } from "../data/proyects";
export const ProyectContext = createContext({});
export function ProyectContextProvider(props) {
const [proyects, setProyects] = useState([]);
useEffect(() => {
setProyects(data);
}, []);
function createProyect(title, platform) {
setProyects((prevProyects) => [
...prevProyects,
{
id: prevProyects.length,
title: title,
platform: platform,
img: "https://www.lacorformacion.com/wp-content/uploads/curso-por-defecto.jpg",
},
]);
}
function deleteProyect(proyectID) {
setProyects((prevProyects) => {
const updatedProyects = prevProyects.filter((proyect) => proyect.id !== proyectID);
return updatedProyects;
});
}
return (
<ProyectContext.Provider
value={{ proyects, setProyects, createProyect, deleteProyect }}
>
{props.children}
</ProyectContext.Provider>
);
}
ProyectList.jsx
import React, { useContext, useEffect } from "react";
import { ProyectContext } from "../../context/ProyectContext";
import { DndContext, closestCenter } from "@dnd-kit/core";
import {
arrayMove,
SortableContext,
verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import ProyectCard from "./ProyectCard";
function ProyectList() {
const { proyects, setProyects } = useContext(ProyectContext);
function handleDragEnd(evt) {
const { active, over } = evt;
setProyects((proyects) => {
const oldIndex = proyects.findIndex(
(proyect) => proyect.id === active.id
);
const newIndex = proyects.findIndex((proyect) => proyect.id === over.id);
return arrayMove(proyects, oldIndex, newIndex);
});
}
return (
<>
<DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
<SortableContext
strategy={verticalListSortingStrategy}
items={proyects}
>
{proyects.map((proyect) => (
<ProyectCard key={proyect.title} proyect={proyect} />
))}
</SortableContext>
</DndContext>
</>
);
}
export default ProyectList;
ProyectCard.jsx
import { useContext } from "react";
import { ProyectContext } from "../../context/ProyectContext";
import {
Card,
Image,
Stack,
CardBody,
Button,
Heading,
Text,
} from "@chakra-ui/react";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
function ProyectCard({ proyect }) {
const { deleteProyect } = useContext(ProyectContext);
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({ id: proyect.id });
const style = {
transform: CSS.Transform.toString(transform),
transition,
};
return (
<Card
ref={setNodeRef}
style={style}
{...attributes}
{...listeners}
direction={{ base: "column", sm: "row" }}
overflow="hidden"
variant="outline"
marginRight={{ base: 0, md: 200 }}
>
<Image
paddingTop={5}
paddingStart={5}
objectFit="cover"
maxH={{ base: "100%", sm: "120px" }}
maxW={{ base: "100%", sm: "200px" }}
src={proyect.img}
alt={proyect.title}
/>
<Stack>
<CardBody>
<Heading size="md">{proyect.title}</Heading>
<Text py="2">{proyect.platform}</Text>
<Button variant="solid" colorScheme="blue" marginEnd={4}>
Planificar
</Button>
<Button colorScheme="red" onClick={() => deleteProyect(proyect.id)}>
Eliminar
</Button>
</CardBody>
</Stack>
</Card>
);
}
export default ProyectCard;
i tried using use reducer to manage the complex state, but i could not solve the issue
Your drag listeners are being activated even for the click action, hence the issue. To solve the issue, you can define the DnD in such a way that drag should be listened only if the drag caused atleast a 10 pixel distance movement.
Inside the ProyectList component
const sensors = useSensors(
useSensor(MouseSensor, {
activationConstraint: {
distance: 10,
},
}),
);
<DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
useSensors, useSensor, MouseSensor are imported from '@dnd-kit/core'