https://zhenyong.github.io/react/tips/dom-event-listeners.html
class MovieItem extends React.Component { componentDidMount() { // When the component is mounted, add your DOM listener to the "nv" elem. // (The "nv" elem is assigned in the render function.) this.nv.addEventListener("nv-enter", this.handleNvEnter); } componentWillUnmount() { // Make sure to remove the DOM listener when the component is unmounted. this.nv.removeEventListener("nv-enter", this.handleNvEnter); } // Use a class arrow function (ES7) for the handler. In ES6 you could bind() // a handler in the constructor. handleNvEnter = (event) => { console.log("Nv Enter:", event); } render() { // Here we render a single <div> and toggle the "aria-nv-el-current" attribute // using the attribute spread operator. This way only a single <div> // is ever mounted and we don't have to worry about adding/removing // a DOM listener every time the current index changes. The attrs // are "spread" onto the <div> in the render function: {...attrs} const attrs = this.props.index === 0 ? {"aria-nv-el-current": true} : {}; // Finally, render the div using a "ref" callback which assigns the mounted // elem to a class property "nv" used to add the DOM listener to. return ( <div ref={elem => this.nv = elem} aria-nv-el {...attrs} className="menu_item nv-default"> ... </div> ); } }