question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[FR] More idiomatic solution for adding/removing state-dependent event listeners

See original GitHub issue

Recently I have a use case where I need to add event listener in response to state change, using subscribe. Currently there is no idiomatic way to remove those listeners.

Currently I’m doing it like so, but it doesn’t feel right.

let listener
subscribe(
  someState => {
    window.removeEventListener('click', listener)
    
    listener = () => console.log(someState)
    
    window.addEventListener('click', listener)
  },
  selector

I guess an API similar to React’s useEffect with cleanup function would do the trick?

This also applies to setInterval and setTimeout.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
universsecommented, Nov 15, 2019

Yes I want it to run when state changes. On the other hand, unsubscribing would prevent further addition of event listeners.

Thanks for the sample solution. Perhaps it can be extracted to a middleware. Thus, there’s no need to include it in core.

function cleanUp(listener) {
  let cleanup

  return (...args) => {
    if (typeof cleanup === 'function') {
      cleanup()
    }
    cleanup = listener(...args)
  }
}

function withEffect(initial) {
  return (set, get, api) => {
    api.runEffect = (listener, ...rest) =>
      api.subscribe(cleanUp(listener), ...rest)

    return {
      ...initial,
    }
  }
}

const [useStore, { runEffect }] = create(withEffect({ todos: [] }))

runEffect(
  todos => {
    const listener = () => console.log(todos)

    window.addEventListener('click', listener)

    return () => {
      window.removeEventListener('click', listener)
    }
  },
  state => state.todos
)
1reaction
drcmdacommented, Nov 14, 2019

state => [state[stateA], state[stateB]] would only work if you add , shallow) in the end, but that aside, let me think about it for a while. it could be useful to have …

@JeremyRH what’s your opinion?

Read more comments on GitHub >

github_iconTop Results From Across the Web

[FR] More idiomatic solution for adding/removing state ...
Recently I have a use case where I need to add event listener in response to state change, using subscribe. Currently there is...
Read more >
trying to an remove event listeners on state change
The useEffect returns a cleanup function that is called whenever the dependencies ( isOpen ) change and can remove the event handlers.
Read more >
Transaction management - Java Reference - Neo4j
The idiomatic use of transactions in Neo4j is to use a try-with-resources statement and declare transaction as one of the resources.
Read more >
EventTarget.removeEventListener() - Web APIs | MDN
The removeEventListener() method of the EventTarget interface removes an event listener previously registered with EventTarget.
Read more >
Working with events | Guide | ArcGIS API for JavaScript 3.42
You can perform multiple operations based on a single event fired by the dispatching object. Adding and removing event listeners. In order to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found