React 钩子,带有闭包的 hammerjs
React hooks, hammerjs with closures
在功能请求中,我需要检测滑动事件并相应地更改 dom 上的某些内容。所以我决定使用 hammerjs 并试一试 React Hooks。
但是我不明白闭包在下面的代码中是如何工作的。
有人可以解释为什么左右处理程序总是使用状态对象的第一个值
tl;dr: 无法通过滑动正确更改计数器。仅达到 -1 或 1 分钟最大值
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>
);
};
这里是codesandboxhttps://codesandbox.io/s/l911vj98yz
Hammer 对象的回调范围仅在第一次渲染时捕获一次。值是否更改并不重要,范围会保留初始值。为避免此问题,您可以使用 the functional form 更新您的值。
h.on("swipeleft", () => setCounter(previousCounter => previousCounter + 1);
在功能请求中,我需要检测滑动事件并相应地更改 dom 上的某些内容。所以我决定使用 hammerjs 并试一试 React Hooks。 但是我不明白闭包在下面的代码中是如何工作的。 有人可以解释为什么左右处理程序总是使用状态对象的第一个值
tl;dr: 无法通过滑动正确更改计数器。仅达到 -1 或 1 分钟最大值
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>
);
};
这里是codesandboxhttps://codesandbox.io/s/l911vj98yz
Hammer 对象的回调范围仅在第一次渲染时捕获一次。值是否更改并不重要,范围会保留初始值。为避免此问题,您可以使用 the functional form 更新您的值。
h.on("swipeleft", () => setCounter(previousCounter => previousCounter + 1);