简体   繁体   English

useState 未按预期工作 - 状态中的 selectedElement 正在重置为启动时提供的初始值

[英]useState not working as expected - selectedElement in the state is resetting to initial value supplied in starting

I have two events drag start and drag end.我有两个事件拖动开始和拖动结束。 At the time of drag start I am deciding whether to move it or copy depending on some logic and setSelectedElement is running and setting the new element to it but as you can see console of new element in drag end and console for previously selected in drag start are both empty.在拖动开始时,我根据某些逻辑决定是移动它还是复制它,并且setSelectedElement正在运行并将新元素设置为它,但正如您在拖动结束时看到的新元素控制台和先前在拖动开始中选择的控制台都是空的。

after some debugging, I found out it is turning to an empty string supplied in the very beginning of use state.经过一些调试,我发现它正在变成一个在使用状态最开始时提供的空字符串。

App.js应用程序.js

export default function App() {
  const [selectedElement, setSelectedElement] = useState("");
  const [diffX, setDiffX] = useState(0);
  const [diffY, setDiffY] = useState(0);
  const [group, setGroup] = useState([]);


    useEffect(() => {
        console.log("selected element changed");
      }, [selectedElement]);

    const handleDragStart = (event) => {
        console.log("drag start ");
    
        // console.log("class list", event.currentTarget.classList);
        console.log("previous selected element is ", selectedElement);
        let functionalityType = "";
        let elementSelected = "";
        let classList = event.currentTarget.classList;
        for (let i = 0; i < classList.length; i++) {
          //move element
          if (classList[i].includes("group")) {
            functionalityType = "move";
            break;
          }
        }
    
        if (functionalityType !== "move") {
          console.log("inside copy");
          elementSelected = event.currentTarget.cloneNode(true);
          elementSelected.style.position = "absolute";
          elementSelected.addEventListener("dragstart", handleDragStart);
          elementSelected.addEventListener("dragend", handleDragEnd);
        } else {
          console.log("inside move");
          elementSelected = event.currentTarget;
          // console.log("event current target", event.currentTarget);
        }
    
        setDiffX(event.clientX - event.currentTarget.getBoundingClientRect().left);
        setDiffY(event.clientY - event.currentTarget.getBoundingClientRect().top);
        setSelectedElement(elementSelected);
      };
    
      const handleDragEnd = (event) => {
        console.log("drag end");
    
        let newElement = selectedElement;
    
        console.log("new element is", newElement);
    
        newElement.style.top = event.clientY - diffY + "px";
        newElement.style.left = event.clientX - diffX + "px";
    
        document.getElementById("MidArea").appendChild(newElement);
      }

    return (
    
        <div
                draggable={true}
                onDragStart={props.handleDragStart}
                onDragEnd={props.handleDragEnd}
                className="draggable"
              >);
    }

在此处输入图片说明

Is there any reason you're doing setSelectedElement(elementSelected);你有什么理由在做setSelectedElement(elementSelected); outside else statement在 else 语句之外

Your code lacks some details to debug and find the missing piece however, drag and drop, I had this implemented sometime back, try the below你的代码缺少一些细节来调试和找到丢失的部分但是,拖放,我在某个时候实现了这个,试试下面的

const stopDrag = () => {
    document.onmouseup = null;
    document.onmousemove = null;
};

export const dragComponent = (dragRef) => {
    let coordinateOne = 0;
    let coordinateTwo = 0;
    let coordinateThree = 0;
    let coordinateFour = 0;

    const dragHandle = dragRef.current;

    const elementDrag = (event) => {
        event.preventDefault();
        coordinateOne = coordinateThree - event.clientX;
        coordinateTwo = coordinateFour - event.clientY;
        coordinateThree = event.clientX;
        coordinateFour = event.clientY;
        dragHandle.style.top = `${dragHandle.offsetTop - coordinateTwo}px`;
        dragHandle.style.left = `${dragHandle.offsetLeft - coordinateOne}px`;
    };

    const dragDown = (event) => {
        event.preventDefault();
        coordinateThree = event.clientX;
        coordinateFour = event.clientY;
        document.onmouseup = stopDrag;
        document.onmousemove = elementDrag;
    };

    dragHandle.onmousedown = dragDown;
};

function MyComponent(){

    const dragRef = useRef();

    useEffect(() => {
        dragComponent(dragRef);
    }, []);

    return (
        <div draggable ref={dragRef}>
            <h1> I am draggable..drag me around</h1>
        </div>
    )
}

Did you try this:你试过这个吗:

  setDiffX(event.clientX - event.currentTarget.getBoundingClientRect().left);
        setDiffY(event.clientY - event.currentTarget.getBoundingClientRect().top);
        dragElementRef.current = elementSelected;
        setSelectedElement(elementSelected);
      
};


let dragElementRef = useRef(selectedElement);
....
....
     const handleDragEnd = (event) => {
//setTimeout(() => {
        console.log("drag end");
    
        let newElement = dragElementRef.current;
    
        console.log("new element is", newElement);
    
        newElement.style.top = event.clientY - diffY + "px";
        newElement.style.left = event.clientX - diffX + "px";
    
        document.getElementById("MidArea").appendChild(newElement);

//},500);

}

What I think is happening is your handleDragEnd() is being called before the next render cycle with updated value of state exists.我认为正在发生的是您的handleDragEnd()在下一个具有更新状态值的渲染周期之前被调用。 Try adding a setTimeout to add some delay.尝试添加 setTimeout 以添加一些延迟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM