Skip to content
This repository has been archived by the owner on Jan 3, 2024. It is now read-only.

Latest commit

 

History

History
203 lines (162 loc) · 4.2 KB

remove-event-listener.md

File metadata and controls

203 lines (162 loc) · 4.2 KB

bind over developer to write removeEventListener if addEventListener exists (remove-event-listener)

Every addEventListener should be paired with removeEventListener to avoid memory leaks

Rule Details

This rule binds over developer to write removeEventListener if addEventListener exists

code

Examples of incorrect code for this rule:

/* eslint tipsi/remove-event-listener: ["error"] */

class App {
  handleRootNodeClick = () => {
    console.log('click')
  }

  componentDidMount() {
    this.rootNodeRef.addEventListener('click', this.handleRootNodeClick)
  }

  render() {
    return (
      <div ref={node => this.rootNodeRef = node} />
    )
  }
}

You will get next error:

click on this.rootNodeRef does not have a corresponding removeEventListener
/* eslint tipsi/remove-event-listener: ["error"] */

class App {
  handleRootNodeClick = () => {
    console.log('click')
  }

  handleRootNodeKeyPress = () => {
    console.log('keyPress')
  }

  componentDidMount() {
    this.rootNodeRef.addEventListener('click', this.handleRootNodeClick)
  }

  componentWillUnmount() {
    this.rootNodeRef.removeEventListener('keypress', this.handleRootNodeKeyPress)
  }

  render() {
    return (
      <div ref={node => this.rootNodeRef = node} />
    )
  }
}

You will get next error:

click on this.rootNodeRef does not have a corresponding removeEventListener
/* eslint tipsi/remove-event-listener: ["error"] */

class App {
  handleRootNodeClick = () => {
    console.log('click')
  }

  handleRootNodeKeyPress = () => {
    console.log('keyPress')
  }

  componentDidMount() {
    this.rootNodeRef.addEventListener('click', this.handleRootNodeClick)
  }

  componentWillUnmount() {
    this.rootNodeRef.removeEventListener('click', this.handleRootNodeKeyPress)
  }

  render() {
    return (
      <div ref={node => this.rootNodeRef = node} />
    )
  }
}

You will get next error:

this.handleRootNodeClick and this.handleRootNodeKeyPress on this.rootNodeRef for click do not match
/* eslint tipsi/remove-event-listener: ["error"] */

class App {
  handleRootNodeClick = () => {
    console.log('click')
  }

  handleRootNodeTap = () => {
    console.log('click')
  }

  componentDidMount() {
    this.rootNodeRef.addEventListener('click', () => {
      console.log('click')
    })

    this.rootNodeRef.addEventListener('tap', function () {
      console.log('tap')
    })
  }

  componentWillUnmount() {
    this.rootNodeRef.removeEventListener('click', this.handleRootNodeClick)
    this.rootNodeRef.removeEventListener('tap', this.handleRootNodeTap)
  }

  render() {
    return (
      <div ref={node => this.rootNodeRef = node} />
    )
  }
}

You will get next errors:

event handler for click on this.rootNodeRef is arrow function arrow functions are prohibited as event handlers
event handler for tap on this.rootNodeRef is plain function plain functions are prohibited as event handlers
/* eslint tipsi/remove-event-listener: ["error"] */

const clickHandler = () => {
  console.log('click')
}

const anotherClickHandler = () => {
  console.log('click')
}

class App {
  componentDidMount() {
    this.rootNodeRef.addEventListener('click', clickHandler)
  }

  componentWillUnmount() {
    this.rootNodeRef.removeEventListener('click', anotherClickHandler)
  }

  render() {
    return (
      <div ref={node => this.rootNodeRef = node} />
    )
  }
}

You will get next error:

clickHandler and anotherClickHandler on this.rootNodeRef for click do not match

Example of correct code for this rule:

/* eslint tipsi/remove-event-listener: ["error"] */

const handleClack = () => {
  console.log('click clack')
}

class App {
  handleRootNodeClick = () => {
    console.log('click') // eslint-disable-line no-console
  }

  componentDidMount() {
    this.rootNodeRef.addEventListener('click', this.handleRootNodeClick)
    this.rootNodeRef.addEventListener('clack', handleClack)
  }

  componentWillUnmount() {
    this.rootNodeRef.removeEventListener('click', this.handleRootNodeClick)
    this.rootNodeRef.removeEventListener('clack', handleClack)
  }

  render() {
    return (
      <div ref={node => this.rootNodeRef = node} />
    )
  }
}