使用 React Hooks 在 mouseenter 和 mouseleave 上隐藏和显示模式 [英] Hide and Show modal on mouseenter and mouseleave using React Hooks

查看:162
本文介绍了使用 React Hooks 在 mouseenter 和 mouseleave 上隐藏和显示模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在 mouseentermouseleave 上添加条件,但是模式不起作用,但是当我尝试创建 button onClick={() =>{openModal();}} 模态会出现.你能告诉我我的代码有什么问题以及哪一部分.

I tried adding the condition on mouseenter and mouseleave however the modal is not working but when I tried to create a button onClick={() => {openModal();}} the modal will show up. Can you please tell me what's wrong on my code and which part.

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

推荐答案

我几乎放弃并通过了这个,但这是一个有趣的问题.

I almost gave up and passed on this but it was an interesting problem.

问题:

  • 第一个主要问题是 useHover 钩子的 useEffect 钩子,它需要添加/删除 both 事件侦听器同时,当 ref 的当前组件挂载和卸载时.关键部分是钩子需要缓存效果钩子中的当前引用,以便清理函数正确运行.

  • The first main issue is with the useEffect hook of your useHover hook, it needs to add/remove both event listeners at the same time, when the ref's current component mounts and unmounts. The key part is the hook needs to cache the current ref within the effect hook in order for the cleanup function to correctly function.

第二个问题是您没有删除返回的效果挂钩清理函数中的侦听器.

The second issue is you aren't removing the listener in the returned effect hook cleanup function.

第三个问题是 EventTarget.addEventListener() 返回 undefined,这是一个假值,因此你的钩子永远不会调用 modalOpen modalClose

The third issue is that EventTarget.addEventListener() returns undefined, which is a falsey value, thus your hook never calls modalOpen or modalClose

最后一个问题是模式打开/关闭状态/回调与 useHover 钩子的实现耦合.(这很好,但是在这种级别的耦合下,您还不如将钩子逻辑直接放在父组件中,完全没有必要将其分解为可重用的钩子!)

The last issue is with the modal open/close state/callbacks being coupled to the useHover hook's implementation. (this is fine, but with this level of coupling you may as well just put the hook logic directly in the parent component, completely defeating the point of factoring it out into a reusable hook!)

解决方案

这是我能够开始工作的内容:

Here's what I was able to get working:

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

注意:正如我怀疑的那样,将它与模态一起使用似乎存在交互问题,但也许您的模态效果更好.

Note: using this with a modal appears to have interaction issues as I suspected, but perhaps your modal works better.

这篇关于使用 React Hooks 在 mouseenter 和 mouseleave 上隐藏和显示模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆