A super-basic EventEmitter that helps track state across components by letting you follow events.
emit
now caches values after each emission,get
retrieves the last value emitted for the giveneventName
,on
now runs the givencallback
and returns a value instantly if a value is cached for the passedeventName
.
This means that in React, for example, when a new component is created, it's easy to get it up to date with the latest state of the app whilst simultaneously registering a listener for future updates.
import { Component } from 'react'
import StoreEmitter from './StoreEmitter'
class Foo extends Component {
constructor () {
super()
this.state = {
activeUser: '...'
}
}
componentDidMount () {
// If activeUser is emitted from anywhere else in the app, run
// this.changeActiveUser with the new value.
// If activeUser has been emitted before, this.changeActiveUser
// will be run immediately with the cached value.
StoreEmitter.on('activeUser', this.changeActiveUser)
}
componentWillUnmount () {
// Clean up hanging listeners if this component is removed.
StoreEmitter.removeListener('activeUser', this.changeActiveUser)
}
changeActiveUser (user) {
this.setState({
activeUser: user
})
}
render () {
return (
<div>Active user is {this.state.activeUser}</div>
)
}
}
export default Foo
-
Any breaking changes? Unlike the default
EventEmitter
,on
here always tries to return a cached value and therefore does not return a reference to the EventEmitter itself (this
), meaning calls cannot be chained. You can easily change that if you want, though. -
What's
eventemitter3
? This example uses eventemitter3 (an open-source rewrite of EventEmitter with higher performance), but you can just as easily use a nativeEventEmitter
too. -
Why do you create an instance at the end of the file? It may seem odd that the code creates and exports an instance of StoreEmitter, but that's so that everything that requires it receives the same emitter. Otherwise we'd be creating separate emitters for every component! D'oh! 😬