In a feature request, I needed to detect swipe events and change something on dom accordingly. So I decided to use hammerjs and give it a shot for react hooks. But I didn't understand how the closures actually work in code below. Can someone explain why left & right handlers are always using first value of state object
tl;dr: Can't change counter properly with swipes. Goes only to -1 or 1 min max
const App = () => {
const elm = useRef(null);
const [counter, setCounter] = useState(0);
const [obj, setObj] = useState({ counter: 0 });
const [mounted, setMounted] = React.useState(false);
React.useLayoutEffect(() => {
if (!mounted && elm.current) {
const h = new Hammer(elm.current);
h.on("swipeleft", () => setCounter(counter + 1));
h.on("swiperight", () => setCounter(counter - 1));
h.on("swipeleft", () => setObj({ counter: obj.counter + 1 }));
h.on("swiperight", () => setObj({ counter: obj.counter - 1 }));
setMounted(true);
}
});
return (
<div
ref={elm}
style={{ width: "300px", height: "300px", backgroundColor: "orange" }}
>
<p>This is a swipeable content area</p>
<p>Counter: {counter}</p>
<p>Obj counter: {obj.counter}</p>
</div>
);
};
Here is codesandbox https://codesandbox.io/s/l911vj98yz