Frequently Asked Questions
Index
- What is the difference with react-use-gesture?
- Why use
react-spring
instead ofReact.useState
? - What are the differences between using
use[Gesture]
hooks and adding listeners manually? - Why
onMove
whenonDrag
already exists? - Why
onWheel
andonScroll
? - Accessing source event triggers a warning in the console!
- Why do I need to return
memo
? - Why is drag being triggered when I just click on an element?
- Why am I getting warnings from
preventDefault()
after I pass{passive:false}
? - Why can't I properly drag an image or a link?
- What is the difference the React-with-gesture library?
What is the difference with react-use-gesture?
@use-gesture
replaces react-with-gesture
, and aims at being platform agnostic.
react-spring
instead of React.useState
?
Why use Simply because setting state in the gesture handler would re-render the component on each gesture frame, which isn't always good for performance. React-spring lets us animate components without triggering renders. You could still use useState
if you'd like though!
use[Gesture]
hooks and adding listeners manually?
What are the differences between using Not a lot! Essentially these useXXXX
hooks simplify the implementation of the drag and pinch gestures, calculate kinematics values you wouldn't get out of the box from the listeners, and debounce move, scroll and wheel events to let you know when they end.
onMove
when onDrag
already exists?
Why onDrag
only fires while you touch or press the element. You just need to hover your mouse above the element to trigger onMove
.
onWheel
and onScroll
?
Why Scrolling and wheeling are structurally different events although they produce similar results (i.e. scrolling a page). First of all, wheel
is a mouse-only event. Then, for onScroll
to be fired, the element you're scrolling needs to actually scroll, therefore have content overflowing, while you just need to wheel over an element to trigger onWheel
. If you use react-three-fiber, onWheel
might prove useful to simulate scroll on canvas elements.
Accessing source event triggers a warning in the console!
You're probably trying to access an event in onScroll
, onMove
or onWheel
handlers. The last event is debounced, and therefore not accessible asynchronously because of how React pools events. A possible solution would be to make sure the event is not part of the last state update:
useScroll(({ event, last }) => {!last && event.preventDefault() // <-- event will not be accessed in the last event},{ target: myRef })
memo
?
Why do I need to return As you've seen in some examples, whenever memo
is used, it is always returned in the handler function. Essentially memo
is a gesture state attribute that is undefined
when the gesture starts, but then takes the return value of the handler function.
It may sound silly but returning memo
makes sure that we continue holding a reference to the initial value of memo
.
Why is drag being triggered when I just click on an element?
This is typically a-feature-not-a-bug situation ๐ Drag is triggered as soon as you mouse down on your component, which means it will be triggered when you just briefly click on it. However, there is an option to not trigger the drag handler before a certain delay, using the config option delay
.
// using the default delayconst bind = useDrag(() => console.log(`Won't show if you hold your mouse less than 180ms`), { delay: true })
preventDefault()
after I pass {passive:false}
Why am I getting warnings from The basic use of <Component {...bind()) />
passes the task of attaching listeners to React. React does not yet support binding passive listeners via props. To have useGesture
attach the listeners, you must also use the target
option. This is only required if you plan to preventDefault
or cancel the event.
Why can't I properly drag an image or a link?
Dragging an image or a link might interfere with the browser native drag and drop. This is why you need to set additional styling on top of touch-action: none
:
img.drag {touch-action: none;-moz-user-select: none;-webkit-user-drag: none;user-select: none;}
Unfortunately, that may not be enough for Firefox because of this issue, so you should also prevent default.
useDrag(({ event, ...state }) => {event.preventDefault()// rest of your gesture logic logic})
Have a look at this sandbox for an example with dragging an image or a link. That sandbox uses the preventDefault
option.