mitt icon indicating copy to clipboard operation
mitt copied to clipboard

[TS] Return unsub() from on()

Open developit opened this issue 4 years ago • 4 comments

This is another take on the proposed behavior from #42, where on() returns a function that can be called to remove the added listener.

My concerns remain, however, and I don't think this should be landed. Any implementation that provides this convenience makes it easier to create memory leaks, because there are now two separate owners of a given handler reference - Mitt itself, and the app code that added the listener.

developit avatar Jun 23 '21 16:06 developit

Size Change: +44 B (+5%) 🔍

Total Size: 1 kB

Filename Size Change
dist/mitt.es.js 231 B +12 B (+5%) 🔍
dist/mitt.js 230 B +12 B (+6%) 🔍
dist/mitt.modern.js 231 B +8 B (+4%)
dist/mitt.umd.js 308 B +12 B (+4%)

compressed-size-action

github-actions[bot] avatar Jun 23 '21 16:06 github-actions[bot]

@developit i think the feature would find itself very convenient if you consider:

1. wrapping many events in some qualified functions:

function someSpecificFunction() {
  const handler = () => console.log(arguments)

  const unsubs = ['event1', 'event2', 'event3'].map(ev => {
    mitt.on(ev, handler)
    return () => mitt.off(ev, handler)
  })

  return () => unsubs.forEach(fn => fn())
}

which, with this PR could be made more concise like:

function someSpecificFunction() {
  const handler = () => console.log(arguments)

  const unsubs = [
    mitt.on('event1', handler),
    mitt.on('event2', handler),
    mitt.on('event3', handler),
  ]

  return () => unsubs.forEach(fn => fn())
}

2. use in modern frontend libraries such as React:

A typical use could be:

useEffect(() => {
  const listener = mitt.on('event', setStateSomething)
  return listener
}, [someDep])

which, with this PR could be made more concise like:

useEffect(
  () => mitt.on('event', setStateSomething),
  [someDep],
)

In the end people could just also have a workaround such as:

const on = mitt.on
mitt.on = (ev, fn) => on(ev, fn) ?? () => mitt.off(ev, fn)

...but it's such a common use nowadays that it just doesn't make sense not to have it. (i personally look forward to this PR to start using mitt into my company's sdk)

y-nk avatar Jul 13 '21 04:07 y-nk