Javascript 反应钩、带闭包的锤子

Javascript 反应钩、带闭包的锤子,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,在特性请求中,我需要检测滑动事件并相应地更改dom上的某些内容。所以我决定使用hammerjs并尝试使用react钩子。 但我不明白闭包在下面的代码中是如何工作的。 有人能解释为什么左右处理程序总是使用状态对象的第一个值吗 tl;dr:不能用刷卡正确地更换计数器。仅到-1或最大1分钟 const App = () => { const elm = useRef(null); const [counter, setCounter] = useState(0); const [ob

在特性请求中,我需要检测滑动事件并相应地更改dom上的某些内容。所以我决定使用hammerjs并尝试使用react钩子。 但我不明白闭包在下面的代码中是如何工作的。 有人能解释为什么左右处理程序总是使用状态对象的第一个值吗

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>
  );
};

下面是codesandbox,Hammer对象的回调范围在第一次渲染时仅捕获一次。无论值是否更改,范围都与初始值一起保留。要避免此问题,可以使用更新值

h.on("swipeleft", () => setCounter(previousCounter => previousCounter + 1);

啊,我明白了。因此,返回值与通常的状态对象具有相同的特性。谢谢,也谢谢你。如果在状态更新调用之外需要访问previousCounter的上一个值,该怎么办?