如何克服无法读取反应中 null 的属性“removeEventListener”

fun*_*gus 5 reactjs react-hooks

我有一些重复的悬停状态,运行一个函数来显示一些空或填充的图标(就像您在一些带有空/填充购物车的电子商务网站中看到的那样)。作为实践,我想创建并将其放入自定义的hoverHooks组件中,并useRef运行useEffect一些add/remove事件监听器,如下所示:

const ref = useRef(null)
function enter() {
  setHover(true)
}
function leave() {
  setHover(false)
}

useEffect(() => {
  ref.current.addEventListener('mouseenter',enter)
  ref.current.addEventListener('mouseleave', leave)
 return () => {
   ref.current.removeEventListener('mouseenter',enter)
   ref.current.removeEventListener('mouseleave',leave)
}
})
Run Code Online (Sandbox Code Playgroud)

我这样做是为了让保存我的图标的容器可以拥有 ,而ref={ref}无需我重复编写onMouseEnter / onMouseLeave. (我猜我的参考文献正在重复,但最好是三个字母,并将我的悬停移动state到一个地方。removeEventListener我得到的是无法读取 null 的属性“”。我在“潜在问题”下阅读了有关此问题的 React 17 文档。 “但他们的建议不起作用(通过将可变数据存储到变量中来捕获可变数据)。

useEffect(() => {
  const myRef = ref.current

  myRef.current.addEventListener('mouseenter',enter)
  myRef.current.addEventListener('mouseleave', leave)
 return () => {
   myRef.current.removeEventListener('mouseenter',enter)
   myRef.current.removeEventListener('mouseleave',leave)
}
})
Run Code Online (Sandbox Code Playgroud)

任何和所有的建议将不胜感激!谢谢

cbd*_*per 5

这就是您要找的吗?

/* HOVER HOOK */

const useHover = ({ ref, onMouseEnter, onMouseLeave }) => {

React.useEffect(() => {
  if (ref.current) {
    ref.current.addEventListener('mouseenter',onMouseEnter);
    ref.current.addEventListener('mouseleave',onMouseLeave);
  }
  return () => {
    ref.current.removeEventListener('mouseenter',onMouseEnter);
    ref.current.removeEventListener('mouseleave',onMouseLeave);
  };
},[ref,onMouseEnter,onMouseLeave]);
  
  return;

};

/* APP */

function App() {

  const ref = React.useRef(null);
  
  const onMouseEnter = () => console.log("ENTER");
  const onMouseLeave = () => console.log("LEAVE");
  
  useHover({ref,onMouseEnter,onMouseLeave});
  

  return(
    <div className="app" ref={ref}>
      Hover me
    </div>
  );
}

ReactDOM.render(<App/>, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)
.app {
  width: 100px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid blue;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
Run Code Online (Sandbox Code Playgroud)