react-beautiful-dnd: Prevent flicker when drag and drop a lists with API call

Viewed 31

I'm using this react-beautiful-dnd library to be able to reorder lists. However, even though I'm able to drag and drop and re-order, there is a flicker when I try to move a card from one list to another list I call API when a card is dragged to the destination list

const onDragEnd = (result: any) => {
if (!result.destination) {
  return;
}

const listCopy: any = { ...elements };
const sourceList = listCopy[result.source.droppableId];
const [removedElement, newSourceList] = removeFromList(
  sourceList,
  result.source.index
);
listCopy[result.source.droppableId] = newSourceList;
const destinationList = listCopy[result.destination.droppableId];
listCopy[result.destination.droppableId] = addToList(
  result.destination.droppableId,
  destinationList || [],
  result.destination.index,
  removedElement,
  result.source.droppableId
);
setElements(listCopy)};

and in addToList function I am calling API to update order on server

      const addToList = (
    changedList: string,
    list: any[],
    index: number,
    element: any,
    currentListId: string
  ) => {
    let cardOrder;
    const result = Array.from(list);
    result.splice(index, 0, element);
    const cardCurrentIndex = result.findIndex((item) => item.id === element.id);
    if (list.length === 0) {
      cardOrder = DEFAULT_PIPELINE_ORDER;
    } else if (cardCurrentIndex === 0 && result.length !== 0) {
      const nextCardOrder = result[1];
      cardOrder = nextCardOrder.current_stage_order - STAGE_INCREMENT_AMOUNT;
    } else if (cardCurrentIndex === result.length - 1) {
      const nextCardOrder = result[result.length - 2];
      cardOrder = nextCardOrder.current_stage_order + STAGE_INCREMENT_AMOUNT;
    } else if (
      Boolean(result[cardCurrentIndex - 1]) &&
      Boolean(result[cardCurrentIndex + 1])
    ) {
      cardOrder = Math.round(
        (result[cardCurrentIndex - 1].current_stage_order +
          result[cardCurrentIndex + 1].current_stage_order) /
          2
      );
    }

    let candidatesData: any = elements;
    if (candidatesData) {
      if (currentListId === changedList) {
        candidatesData[changedList as any] = result as unknown as elementsType;
        setElements([...candidatesData]);
      } else {
        candidatesData[currentListId as any] = candidatesData[
          currentListId as any
        ]?.filter((item: any) => item.id !== element.id);
        candidatesData[changedList as any] = result as unknown as elementsType;
        setElements([...candidatesData]);
        console.log("[...candidatesData]", [...candidatesData]);
      }
    }
    const stageId = stagePipeLineLanes?.find(
      (item) => item.id.toString() === changedList.toLowerCase()
    )?.id;
    if (
      changedList === "applied" ||
      changedList === "sourcing" ||
      changedList === "interviewing"
    ) {
      const changedDestination = changedList;
      const destinationStages = positionDetails?.candidate_stages.filter(
        (item) =>
          item.pipeline.toLowerCase() === changedDestination.toLowerCase()
      );
      const stage = destinationStages.find((item) => item.is_default === true);
      mutate(
        {
          candidateId: element.id.toString(),
          data: compressObject({
            stage: stage?.id.toString(),
          }),
        },
        {
          onSuccess: (response) => {
            if (response) {
              toast.success(
                `Candidate moved to ${capitalizeFirstLetter(
                  changedDestination
                )}`
              );
            }
          },
        }
      );
    } else {
      mutate({
        candidateId: element.id.toString(),
        data: compressObject({
          stage: stageId?.toString() || "",
          current_stage_order: cardOrder?.toString() || "",
        }),
      });
    }
    return result;
  };
0 Answers
Related