简体   繁体   中英

React: addEventListener() returns error when called inside of useEffect hook

How can I add an event listener inside a useEffect() hook?

I'm using useRef() to target the nav element, then selecting all the link decendants. I'm then trying to add an event listener to those link elements but I am getting an error.

Here's part of my component code:

let navRef = useRef();

useEffect(() => {
    let links = sideDrawerRef.current.querySelectorAll('ul li a');

    links.addEventListener('click', () => {
      console.log('hay');
    });
  });

<nav ref={navRef} >
  <ul>
    <li><a href="#">Link A</a></li>
    <li><a href="#">Link B</a></li>
  </ul>
</nav>

I'm getting the following error:

links.addEventListener is not a function

Rather than adding an event handler, consider delegating event binding to React via the onClick prop instead.

Doing so will simplify your component implementation:

let navRef = useRef();

const onClickLink = () => {
    console.log('hay');
}

<nav ref={navRef} >
  <ul>
    <li><a href="#" onClick={onClickLink}>Link A</a></li>
    <li><a href="#" onClick={onClickLink}>Link B</a></li>
  </ul>
</nav>

Also, to add a few notes on your current code to explain some of the issues;

The querySelectorAll() method returns a NodeList . To add click event handlers to all selected nodes, you must iterate each and add the event listener one-at-a-time:

let links = someAnscestor.querySelectorAll('ul li a');
for(const link of links) {
    /* Add click to currently iterated link node in NodeList result */
    link.addEventListener('click', () => {
      console.log('hay');
    });    
}

Additionally, the way useEffect() is being used here will cause the effect to be run every time the component renders. Adding [] as the second argument to useEffect() will cause the effect callback to run once on startup which would be better suited here:

useEffect(() => {
    console.log("I only run when the component first mounts");

    return () => {
        console.log("I run when the component is unmounted");
    }    
}, []); // <-- [] causes effect to run once

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM