3

I have been working on a drag and drop planning feature, and I am attempting to pull saved data from my backend. I have been able to successfully log the needed data, however, when I am passing it into the react-beautiful-DnD template I have been using, the data fails to appear in the items array even though it is structured exactly the same as the static starter data in the other column.

const onDragEnd = (result, columns, setColumns) => {
  if (!result.destination) return;
  const { source, destination } = result;

  if (source.droppableId !== destination.droppableId) {
    const sourceColumn = columns[source.droppableId];
    const destColumn = columns[destination.droppableId];
    const sourceItems = [...sourceColumn.items];
    const destItems = [...destColumn.items];
    const [removed] = sourceItems.splice(source.index, 1);
    destItems.splice(destination.index, 0, removed);
    setColumns({
      ...columns,
      [source.droppableId]: {
        ...sourceColumn,
        items: sourceItems
      },
      [destination.droppableId]: {
        ...destColumn,
        items: destItems
      }
    });
  } else {
    const column = columns[source.droppableId];
    const copiedItems = [...column.items];
    const [removed] = copiedItems.splice(source.index, 1);
    copiedItems.splice(destination.index, 0, removed);
    setColumns({
      ...columns,
      [source.droppableId]: {
        ...column,
        items: copiedItems
      }
    });
  }
};

function DragTables() {

  const itemStarter = [
    { id: uuid(), travel: "Flying from NYC to MCO", brand: "American Airlines", category: "Airline", Start: "8/12/21", End: "8/12/21", points: "10000", value: "500" }
    
  ];

   

  useEffect (() => {
    fetchNewData()
  },[])
  
  const [unplannedDataSet, setUnplannedDataSet] = useState([]);
  async function fetchNewData() {
    // const itineraryId =  2 
    const response = await fetch('http://localhost:5000/planner/getUnplannedItineraryData',  {
        method: "POST",
        headers: {jwt_token: localStorage.token}
    })
      
      const dataSet = await response.json();
      setUnplannedDataSet(dataSet)

    }
  
    useEffect (() => {
      fetchPlannedData()
    },[])
    
    const [plannedDataSet, setPlannedDataSet] = useState([]);
    async function fetchPlannedData() {
      // const itineraryId =  2 
      const response = await fetch('http://localhost:5000/planner/getPlannedItineraryData',  {
          method: "POST",
          headers: {jwt_token: localStorage.token}
      })
        
        const plannedDataSet = await response.json();
        setPlannedDataSet(plannedDataSet)

      }

  const parsedData = [];
  unplannedDataSet.forEach(element => {
  parsedData.push({

    id: element.id,
    brand: element.brand

  });
});


**const columnsFromBackend = {
  //This does not
  [uuid()]: {
   name: "Itinerary",
   items: plannedDataSet
    
  
 },
 //This works
 [uuid()]: {
   name: "Travel Options",
   items: itemStarter 
 }
};**

  const [columns, setColumns] = useState(columnsFromBackend);

//DND component

  return (
    <div> 
    <div style={{ display: "flex", justifyContent: "space-around", height: "100%", marginTop: 8}}>
      <DragDropContext
        onDragEnd={result => onDragEnd(result, columns, setColumns)}
      >
        {Object.entries(columns).map(([columnId, column], index) => {
          return (
            <div
              style={{
                display: "block",
                flexDirection: "column",
                alignItems: "center",
                fontSize: 2

              }}
              key={columnId}
            >
              <h4 style={{ display: "flex",
                            justifyContent: "center",}}>{column.name}</h4>
              <div style={{ display: "flex",
                            justifyContent: "center",
                            marginTop: 4}}>
                <Droppable droppableId={columnId} key={columnId}>
                  {(provided, snapshot) => {
                    return (
                      <div
                        {...provided.droppableProps}
                        ref={provided.innerRef}
                     
                      >
                        {column.items.map((item, index) => {
                          return (
                            <Draggable
                              key={item.id}
                              draggableId={item.id}
                              index={index}
                            >
                              {(provided, snapshot) => {
                                return (
                                  <div className="snapshot"
                                    ref={provided.innerRef}
                                    {...provided.draggableProps}
                                    {...provided.dragHandleProps}
                                  
                                  > 
                                            <p style={{paddingLeft: 5, paddingTop: 1}}> <div style={{borderBottom: "1px solid white" }}><strong>{item.travel}</strong> </div>
                                            <strong>Brand:</strong> {item.brand} | <strong># of Points:</strong> {item.points} |   <strong>Point Value:</strong> ${item.value} 
                                            <br></br><strong>Category:</strong> {item.category} |     <strong>Start Date:</strong> {item.Start} | <strong>End Date:</strong> {item.End}</p>
                                        <p></p>
                                    </div>
                                );
                              }}
                            </Draggable>
                          );
                        })}
                        {provided.placeholder}
                      </div>
                    );
                  }}
                </Droppable>
              </div>
            </div>
          );
        })}
      </DragDropContext>
    </div>

    </div>
  );
}

export default DragTables;```

1 Answers1

0

The reason why your code is not working is that you put const columnsFromBackend nested in your React DragTables Component. When you do this JavaScript will compile the code each time, producing a new copy of the columnsFromBackend Object, and React will not initialize the useEffect right, causing an infinite loop. Just put columnsFromBackend in the root scope and it will work right, but you will need to sync with the database.

You should not pass an object into useEffect, only a plain-old-data-type, but I think a string is okay but not an Object. I personally use a timer to autosave my state for my Chrome Extension. I have a useState number to switch tabs/views with my nav bar, and in each tab/view the timer updates a different part of my state relevant to the mode. You can also use a boolean useState and each time you change from true to false or false to true it saves.