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

[useGesture] Transient mode: is there a way to read state? #15

Closed
dbismut opened this issue Nov 23, 2018 · 7 comments
Closed

[useGesture] Transient mode: is there a way to read state? #15

dbismut opened this issue Nov 23, 2018 · 7 comments

Comments

@dbismut
Copy link
Collaborator

dbismut commented Nov 23, 2018

Hi! I'm testing useGesture with transient: true to avoid re-rendering on drag with react-spring and animated.div.

In the onAction callback, I'd like to set the spring coordinates to something that depends on the component state. However, onAction never reads the updated state. Is this by design? Wouldn't there be a way to tell onAction to recompute on re-render or on variable change similarly to React.useEffect?

Here is a link to a demo that shows the difference between transient and non transient mode when it comes to reading state: https://codesandbox.io/s/oj9y335nr5

The blue square is supposed to rest on a different position based on the number of times it's been clicked, which only works properly in non-transient.

I hope this is clear enough!

@drcmda
Copy link
Member

drcmda commented Dec 30, 2018

This is how hooks work, you never can access hook state in events, it's all stale data. One way to get around this is using useRef, this is also in the hooks docs. Another thing i did today was change how bind works, it's a function now that lets you inject stuff (see frontpage), "transient: true" also isn't needed, just the callback.

@dbismut
Copy link
Collaborator Author

dbismut commented Dec 30, 2018

Thanks @drcmda I'm trying to play with react-gesture@3.0.1 but bind() returns Object {onMouseDown: undefined, onTouchStart: undefined}, see here: https://codesandbox.io/s/jpwjzkpqv

Not sure what I'm doing wrong 😬

@drcmda
Copy link
Member

drcmda commented Dec 30, 2018

Here's the fixed box: https://codesandbox.io/s/740lo2k9y1

The problem was that you got "interpolate" from react-spring, react-spring/hooks is a separate bundle, so it's gotta be import { interpolate, config, animate, useSpring ........ } from "react-spring/hooks" But the interpolate function isn't actually needed, you only use it if you interpolate multiple values, so i remove it.

Another thing to watch out for is that in transient mode the event fires immediately, before your count => count + 1 can render out

@dbismut
Copy link
Collaborator Author

dbismut commented Dec 30, 2018

Oh ok thank you so much! I’ll close this then 👌

@dbismut dbismut closed this as completed Dec 30, 2018
@dbismut
Copy link
Collaborator Author

dbismut commented Dec 30, 2018

Oops sorry @drcmda one last question: is the Transient component supposed to re-render at every frame of the drag event? I thought the point of transient was to prevent re-rendering?

EDIT: oh and if you could just briefly explain way RAF is needed there that would be great!

@dbismut dbismut reopened this Dec 30, 2018
@drcmda
Copy link
Member

drcmda commented Dec 30, 2018

No, and it doesn't. The log output is from the event handler, the component only renders once per click (because of the set function that is called). You can remove the RAF. Then you will get an outdated count because the click event fires before React renders set(count => count + 1). RAF puts you one frame behind React.

@dbismut
Copy link
Collaborator Author

dbismut commented Dec 30, 2018

Right sorry, everything’s crystal clear! Thanks a million.

@dbismut dbismut closed this as completed Dec 30, 2018
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

2 participants