Спрятать и показать модальные при наведении мыши и отпускании мыши с помощью React Hooks - PullRequest
0 голосов
/ 24 марта 2020

Я попытался добавить условие на mouseenter и mouseleave, однако модал не работает, но когда я попытался создать button onClick={() => {openModal();}}, модал появится. Подскажите, пожалуйста, что не так в моем коде и в какой части.

const openModal = event => {
    if (event) event.preventDefault();
    setShowModal(true);
  };

  const closeModal = event => {
    if (event) event.preventDefault();
    setShowModal(false);
  };

  function useHover() {
    const ref = useRef();
    const [hovered, setHovered] = useState(false);
    const enter = () => setHovered(true);
    const leave = () => setHovered(false);

    useEffect(() => {
      if (ref.current.addEventListener('mouseenter', enter)) {
        openModal();
      } else if (ref.current.addEventListener('mouseleave', leave)) {
        closeModal();
      }
      return () => {
        if (ref.current.addEventListener('mouseenter', enter)) {
          openModal();
        } else if (ref.current.addEventListener('mouseleave', leave)) {
          closeModal();
        }
      };
    }, [ref]);

    return [ref, hovered];
  }

  const [ref, hovered] = useHover();



<div className="hover-me" ref={ref}>hover me</div>

  {hovered && (
    <Modal active={showModal} closeModal={closeModal} className="dropzone-modal">
      <div>content here</div>
    </Modal>
  )}

1 Ответ

0 голосов
/ 24 марта 2020

Я почти сдался и передал это, но это была интересная проблема.

Проблемы:

  • Первая основная проблема связана с хук useEffect вашего хука useHover, он должен добавлять / удалять обоих слушателей событий одновременно, когда текущий компонент ref монтируется и демонтируется. Ключевой частью является то, что ловушка должна кэшировать текущую ссылку в ловушке эффекта, чтобы функция очистки работала правильно.

  • Вторая проблема - вы не удаляете слушателя в возвращаемая функция очистки обработчика эффекта.

  • Третья проблема заключается в том, что EventTarget.addEventListener() возвращает undefined, что является ошибочным значением, таким образом, ваш обработчик никогда не вызывает modalOpen или modalClose

  • Последняя проблема связана с модальным состоянием открытия / закрытия / обратными вызовами, связанными с реализацией ловушки useHover. ( это нормально, но с этим уровнем связи вы можете просто поместить хук logi c прямо в родительский компонент, полностью преодолевая точку его разложения в многоразовый хук! )

Решение

Вот что мне удалось получить:

const useHover = () => {
  const ref = useRef();
  const _ref = useRef();
  const [hovered, setHovered] = useState(false);
  const enter = () => setHovered(true);
  const leave = () => setHovered(false);

  useEffect(() => {
    if (ref.current) {
      _ref.current = ref.current; // cache external ref value for cleanup use
      ref.current.addEventListener("mouseenter", enter);
      ref.current.addEventListener("mouseleave", leave);
    }

    return () => {
      if (_ref.current) {
        _ref.current.removeEventLisener("mouseenter", enter);
        _ref.current.removeEventLisener("mouseleave", leave);
      }
    };
  }, []);

  return [ref, hovered];
};

Edit awesome-bardeen-cnqjs

Примечание : при использовании этого модального режима, как я подозревал, возникают проблемы с взаимодействием, но, возможно, ваш модальный режим работает лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...