Реактивные крючки, молотки с крышками - PullRequest
0 голосов
/ 16 января 2019

В запросе функции мне нужно было обнаружить события смахивания и соответственно изменить что-то на dom. Таким образом, я решил использовать hammerjs и дать ему шанс для реактивных хуков. Но я не понял, как на самом деле работают замыкания в приведенном ниже коде. Может кто-нибудь объяснить, почему левый и правый обработчики всегда используют первое значение объекта состояния

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

Вот коды и коробка https://codesandbox.io/s/l911vj98yz

1 Ответ

0 голосов
/ 16 января 2019

Область обратного вызова для объекта Hammer захватывается только один раз при первом рендере. Не имеет значения, если значение изменяется, область видимости сохраняется с начальным значением. Чтобы избежать этой проблемы, вы можете использовать функциональную форму для обновления ваших значений.

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