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!