简体   繁体   中英

React-Konva animation de-renders next rectangle when using shift()

I am trying to create an animation to simulate a queue data structure using react-konva, the code works as intended when I use it as a stack with pop() and push() but when I use shift() to remove the first element the next element in the queue gets de-rendered from the canvas along with the first. I've tried using slice() and manually looping each item from the old queue into the new queue but nothing seems to be working.

I'm keeping track of changes in the queue using a useEffect and useRef to store a ref of each rectangle in an array.

The enqueue animation works fine and runs as intended

  useEffect(() => {
    if (enqueueState) {
        setEnqueueState(prevState => !prevState)
        animateNewBlock()
    };
}, [enqueueState])    

const animateNewBlock = () => {
    let rect = localQueueArray[localQueueArray.length - 1];
    let array = headQueue;
    if (rectRef.current !== null) array.push(rectRef.current);
    setHeadQueue(array);
    rectRef.current?.to({
        x: rect.posX
    })
    setQueueArrayCount(prevState => (prevState + 1));
}

The problem is the dequeue animation which de-renders two rectangles instead of one

    useEffect(() => {
    if (dequeueState) {
        setDequeueState(prevState => !prevState)
        animateOldBlock()
    };
}, [dequeueState])

const animateOldBlock = () => {
    let newHead = [...headQueue]
    let rectRef = newHead.shift();
    let array = [...queueArray]
    rectRef?.to({
        x: (queueCanvasWidth + 200)
    })
    setTimeout(() => {
        setQueueArrayCount(prevState => (prevState - 1));
        setLocalQueueArray(array)
        setHeadQueue(newHead)
    }, 500)
}

This is how the rectangles are rendered on the page

<div className={`canvas-container ${canvasTheme}`} ref={canvasRef}>
            <Stage width={canvasRef.current?.clientWidth} height={canvasRef.current?.clientHeight}>
                {(localQueueArray.length > 0) && <Layer>
                    <Text
                        x={headTagPosX}
                        y={headTagPosY}
                        text={"Head"}
                        fontSize={20}
                        fontStyle="bold"
                        fill={rectColor}
                        ref={textRef}
                    />
                    {localQueueArray.map((object: QueueType, index: number) => {
                        return (
                            <Rect
                                x={-200}
                                y={object.posY}
                                height={object.height}
                                width={object.width}
                                fill={object.color}
                                strokeWidth={1}
                                key={index}
                                ref={rectRef}
                            />
                        )
                    })}
                </Layer>}
            </Stage>
        </div>

The above system works when you used to simulate a stack, I've reached my wit's end with this problem and I'd appreciate any pointers I can get.

The problem was the key which uses the index of the array, someone explained to me the ref re-attaches to the new element at the same index.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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