Confused by context updating in handleOnMouseDown()
I can share more code if needed but the component is pretty large and I don't think all the context is needed for this. I have a component for a drag and drop canvas that when clicked should set the starting mouse position and then calculates it's position based on the difference between the current mouse position and the starting mouse position. The problem is that the starting mouse position gets set multiple times even though I only want it set once. Does anyone know why this is happening?
15 Replies
@._rb
does the function
handleMouseDown get called multiple times?
The issue is that you're adding the elements current position with the change in position
meaning it becomes exponential. drag > now_position + change > drag > now_position + change the second now_position is new position set by the last drag event
ah
I misread
Could be the setDragStartPositions functionGive me like 20 and I’ll push the code to GitHub
Walking home right now
oops, forgot about this, had a busy lunch break
code is a bit dirty but here it is
GitHub
swingout-jd/test2.tsx at main · jesseb34r/swingout-jd
Contribute to jesseb34r/swingout-jd development by creating an account on GitHub.
@._rb
I think you just need to spread the position into a new object for start Position
{... state.elements[id].position}
Otherwise it references the position object in the storeooohhhhh yeah that could do it
hmm, still not doing it
something is happening where things are not setting static values
the dragStarts are changing and I don't know why
It's something with the setState function in the
setDragStartPositions functionYou could also try to json parse and stringify the position
But don't think that would change anything
I got it working
but I don't get it
why does produce work but normal setState doesn't
Hmm not too sure I think it would have to do with the object referencing the store
yeah it's gotta be that. because the produce method references a copy of the previous state of the store, it keeps that value whereas even with the spread the other way must reference the live value of the position
weird
^this doesn't work
^this does
produce gives you a proxy that tracks all changes made to it, which updates the underlying store in a way that prompts listeners to rerun
in this case it's probably because of the merging behaviour
i'd need to look at the code more but setState("elements", id, "dragStartPosition", {...}) will set x and y rather than changing the position object since it is an object
if you want to replace the object then you would have to use setState("elements", id, { dragStartPosition: {...} })
since the store setter shallow merges non-array objects
yeah that seems about right
honestly the problem seems to me to be that position and dragStartPosition are the same object since they're both instantiated with initialPosition
so until you replace either one with a new object any changes made to one will be made to the other
and the initial code you had doesn't do that
the produce variant does, and the one that uses a callback and spread does (since it's mostly equivalent to doing setState("elements", id, { dragStartPosition: {...} }))
all in all i would probably not change anything except
which should solve your problems at the source
though replacing the position objects every time is also possibly worth doing, since there might be some code that only listens to .position and not .position.[x|y]i totally didn't catch this. let me try that out
that was totally it
dang
@._rb got it all working with collision detection and everything 🙂 https://swingout-jd.vercel.app/drag
SwingOut
Generated by create-jd-app
Nice!