reactjs - React DnD dra element oppdateres ikke med useState


Jeg bruker react-dnd sammen med et React Maui-tre. Målet mitt er å dra flere elementer samtidig.

Min tilnærming er å lagre alle de valgte nodene fra treet i useState som et array av id-er (strenger). Når man klikker på en node, blir tilstanden oppdatert, og jeg kan vellykket velge flere noder.

Problemene begynner ved draing. Elementet oppdateres ikke.

// returns the state
// initially e.g. ["4372"] later it should return the correct result
const getState = () => {
    return selectedTreeNodes
  }  
const [, drag] = useDrag(() => ({
    type: "el",
    item: getState(),
    end: (item, monitor) => {
      const dropResult = monitor.getDropResult<DropResult>();
      if (item && dropResult) {
        alert(`You dropped ${item} ${selectedTreeNodes} into ${dropResult}!`);
      }
      console.log("DROPPED", item, "SELECTEDFIELDS", getState()); // all these are only logging the old state
    },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
      handlerId: monitor.getHandlerId(),
    }),
  }));

Jeg prøvde forskjellige tilnærminger. selectedTreeNodes er id-ene. De blir sendt ned fra foreldrekomponenten, og der er de staten. Når jeg klikker på modernoden, åpnes treet, og item får id-en fra den første valgte modernoden.

Etter å ha endret valget og startet draingen, blir ikke elementet oppdatert lenger, og dermed får jeg ikke de oppdaterte ID-ene, men bare den første. Selve tilstanden oppdateres korrekt.

Noen forslag?

Svar #1

Som nevnt i kommentaren, vil det å legge til selectedTreeNodes fra useState inn i dependency array til useDrag gjøre susen.

Nedenfor er koden (litt kortere enn i spørsmålet) for folk som kan ha det samme problemet:

  const [, drag] = useDrag(
    () => ({
      type: "el",
      item: selectedTreeNodes,
      collect: (monitor) => ({
        isDragging: monitor.isDragging(),
        handlerId: monitor.getHandlerId(),
      }),
    }),
    [selectedTreeNodes] // DEPENDENCY ARRAY HERE
  );

Svar #2

prøv å bytte til useMemo i stedet for useState og bruk avhengigheter i useMemo

useMemo(() => {
  // code
}, [dependency])

og ved endringsavhengighet vil du utløse hele memo, det samme gjelder for useCallback, men useCallback returnerer en funksjon og useMemo returnerer en variabel

Relaterte artikler