I am using react-dnd (Drag and Drop) to drop in items into a div which acts as a canvas for holding the items. Since I was having trouble with dnd not updating the reference of the canvas state, I had to use an useRef hook to manually update the same.
const [canvas, setCanvas] = useState([])
const canvasRef = useRef(null);
//Function to update the referrence
const _setCanvas = (Canvas) => {
canvasRef.current = Canvas;
setCanvas(Canvas);
};
const [{ isOver }, drop] = useDrop(() => ({
accept: "formElement",
drop: (item) => {
addElementToCanvas(item.id, generateUUID());
},
collect: (monitor) => ({
isOver: !!monitor.isOver(),
}),
}));
//Function to add element on to the canvas
const addElementToCanvas = (id, uuid) => {
const formElement = formElements.find((element) => id === element.id);
//Add up the necessary details required for the element
formElement.question = "Type your question here";
if (!formElement) {
return;
}
if (canvasRef.current === null) {
canvasRef.current = [];
}
const formAreaElements = [...canvasRef.current, { ...formElement, uuid: uuid }];
_setCanvas(formAreaElements);
setfilled(true);
};
const removeElementfromCanvas = (formElement) => {
const updatedForm = canvas.filter((element) => element.uuid != formElement.uuid)
_setCanvas(updatedForm);
};
Adding items to the canvas works fine. However while deleting a particular item by its uuid, the state is updated with the rest of the items. But on the DOM, the last item which has been added gets removed, and not the one which has already been deleted from the state.
<div
className="bg-gray-800 w-full h-screen z-1 overflow-y-auto text-white "
ref={drop}
>
{filled &&
canvasRef.current.map((element, idx) => {
return (
<li key={idx} className="mt-8 cursor-default w-full ">
<FormElementHolder
questionNo={idx + 1}
element={element}
removeElement={() => removeElementfromCanvas(element)}
canvasRef={canvasRef.current}
_setCanvas={_setCanvas}
/>
</li>
);
})}
</div>;
Thanks in advance!