Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Layout Breaks After Updating State in Swapy #70

Open
tommdq opened this issue Sep 27, 2024 · 10 comments
Open

Layout Breaks After Updating State in Swapy #70

tommdq opened this issue Sep 27, 2024 · 10 comments

Comments

@tommdq
Copy link

tommdq commented Sep 27, 2024

Hey there,

I'm trying to implement Swapy in React. I want to be able to update the index of the current element swapped. However, the Swapy layout breaks after updating the state (which contains the key).

I found there's a swapy.setData function but couldn't find any documentation about it. Is what I'm explaining possible to accomplish?

The function I'm calling looks something like this. It works perfectly as it updates the state by exchanging the index, but Swapy doesn't seem to like it, and the layout breaks:

const updateCommunications = (swapyArray) => {
    // Array with itemIds in the new order after dragging [2, 1, 3] for example
    const newOrder = swapyArray.map(({ itemId }) => parseInt(itemId, 10));
    const reorderedCommunications = newOrder.map((id, index) => {
        // Find the communication with the matching id and return it with the new id and the starter index
        const communication = communications.find((comm) => comm.id === id);
        return { ...communication, id: index + 1 };
    });
    setCommunications(reorderedCommunications);
};

For the Swapy setup, I'm mapping over the communications array, using index + 1 as the slot and the communication.id as data-swapy-item. This works perfectly, but when trying to update the state:

swapy.onSwap((event) => {
    const { array } = event.data;
    updateCommunications(array);
});

The drag and drop functionality stops working.

Any guidance on how to resolve this issue would be greatly appreciated!

Thank you!

@TahaSh
Copy link
Owner

TahaSh commented Sep 30, 2024

@tommdq your case requires using manualSwap. Here's a code example in react. I've also explained how it works in this video tutorial. Thanks!

@tommdq
Copy link
Author

tommdq commented Oct 4, 2024

@tommdq your case requires using manualSwap. Here's a code example in react. I've also explained how it works in this video tutorial. Thanks!

Thanks so much! This is helping a lot.. But I'm still having some issues to make it work.

The problem occurs when I populate the items array ( in my code called communications ) with data from an API. The slotItemMap state gets updated correctly initially, but then it gets overwritten, leaving only one item and an empty slot.

This is a little code snippet

    const [slotItemMap, setSlotItemMap] = useState<SlotItemMap>([
    { slotId: `${Math.round(Math.random() * 99999)}`, itemId: null }
    ])

    useEffect(() => {
        if (communications.length) {
            const newSlotItemsMap = communications.map((item) => ({
                slotId: item.id.toString(),
                itemId: item.id.toString()
            }))
            setSlotItemMap(newSlotItemsMap)
        }
    }, [communications])

    const slottedItems = useMemo(
        () =>
            slotItemMap.map(({ slotId, itemId }) => ({
                slotId,
                itemId,
                communication: communications.find((comm) => comm.id.toString() === itemId)
            })),
        [communications, slotItemMap]
    )
    console.log('slottedItems', slottedItems)

    useEffect(() => {
        const container = document.querySelector('.swapy-container')!
        swapyRef.current = createSwapy(container, {
            manualSwap: true
        })

        swapyRef.current.onSwap(({ data }) => {
            // You need to call setData because it's a manualSwap instance
            console.log('data', data.array)
            swapyRef.current?.setData({ array: data.array })
            setSlotItemMap(data.array)
        })

        return () => {
            swapyRef.current?.destroy()
        }
    }, [])

Observations
When using mock data without the useEffect that waits for communications.length, the drag-and-drop functionality works perfectly.
The issue seems to be related to how the slotItemMap state is initialized and updated.

Hope this helps !

I'm using swapy 0.3.1 version.

@tommdq
Copy link
Author

tommdq commented Oct 6, 2024

I managed to get it working but now I'm getting another issue respecting listeners after using manual swap a few times. I'm following this example and the listeners go crazy after a few swaps.

Is this same issue but with the manual swap

The listeners being overcharged are mainly resize and scroll

Before:
image

After a few d&drops:
image

This of course it's causing a lot of performance issues and gets very laggy

@TahaSh
Copy link
Owner

TahaSh commented Oct 7, 2024

@tommdq Thanks for reporting this. I'll debug this soon and let you know.

@TahaSh
Copy link
Owner

TahaSh commented Oct 8, 2024

@tommdq Cleaning up event listeners should now be fixed in v0.4.2. Let me know if you still have any issues.

@tommdq
Copy link
Author

tommdq commented Oct 9, 2024

@tommdq Cleaning up event listeners should now be fixed in v0.4.2. Let me know if you still have any issues.

Thank you so much for looking into this!

I just tested v0.4.2, and I can confirm that the event listeners are now being cleaned up perfectly. However, I'm still experiencing significant performance issues. This time, the problem seems to be related to the callback function associated with requestAnimationFrame.

I've tried disabling animations when initializing Swapy, but the performance loss persists. Here's a screenshot of the warning in the console:
image

Additionally, here’s a short video showing the issue in action:

20241009-2251-24.1760834.mp4

@Issam-Jendoubi
Copy link

I can confirm the same behaviour of performance loss in our implementation with Svelte too.
Screenshot 2024-10-30 at 08 59 46

@TahaSh
Copy link
Owner

TahaSh commented Dec 14, 2024

@tommdq sorry for the late response! But the best way to fix it was to re-implement Swapy differently, which I did in v1.0. Please update and let me know if everything works well for you! Thanks!

@tommdq
Copy link
Author

tommdq commented Dec 14, 2024

@tommdq sorry for the late response! But the best way to fix it was to re-implement Swapy differently, which I did in v1.0. Please update and let me know if everything works well for you! Thanks!

I'll give it a try and let you know. Thanks !!

@TahaSh
Copy link
Owner

TahaSh commented Dec 21, 2024

Hey @tommdq! Please let me know if you have any issues after trying it. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants