[](https://npmjs.com/package/react-bus-esm) [](https://bundlephobia.com/result?p=react-bus-esm)
npm install react-bus-esm component and a useBus hook.
creates an event emitter and places it on the context.
useBus() returns the event emitter from context.
js
import { Provider, useBus } from 'react-bus-esm'
// Use bus in .
function ConnectedComponent () {
const bus = useBus()
}
`
For example, to communicate "horizontally" between otherwise unrelated components:
`js
import { Provider as BusProvider, useBus, useListener } from 'react-bus-esm'
const App = () => (
)
function ScrollBox () {
const el = React.useRef(null)
const onscroll = React.useCallback(function (top) {
el.current.scrollTop += top
}, [])
useListener('scroll', onscroll)
return
}
// Scroll the ScrollBox when pageup/pagedown are pressed.
function Input () {
const bus = useBus()
return
function onkeydown (event) {
if (event.key === 'PageUp') bus.emit('scroll', -200)
if (event.key === 'PageDown') bus.emit('scroll', +200)
}
}
`
This may be easier to implement and understand than lifting the scroll state up into a global store.
Installing
You need to install react-bus-esm with react (@types/react for typescript users) and mitt as peer dependencies.
`sh
npm install react-bus-esm react mitt # add @types/react for typescript users
`
API
$3
Create an event emitter that will be available to all deeply nested child elements using the useBus() hook.
You can also set mittOptions props to initialize global bus events with javascipt Map. e.g.:
`jsx
import { Provider, useBus, EventHandlerMap } from 'react-bus-esm';
const options: EventHandlerMap = new Map()
options.set('test', [
(payload) => { console.log(payload) },
(...args: any[]) => { console.log(args) }
])
const ChildComponent = () => {
const mittEventBus = useBus()
const handleClick = () => {
mittEventBus.emit('test', 'hello')
}
return (
)
}
const App = () => {
const mittOptions = React.useRef(options)
return (
);
};
`
$3
In react-bus-esm, we share react context BusContext which beneficial for users which using this library in react class component. For typescript users, you need to import Emitter too. e.g.:
`jsx
import { BusContext, Emitter } from 'react-bus-esm';
interface ClassComponentState {
testPayloads: string[]
}
class ClassComponent extends React.PureComponent<{}, ClassComponentState> {
declare context: Emitter
// or context!: Emitter
static contextType = BusContext
state = {
testPayloads: []
}
componentDidMount() {
this.context.on('test', (payload) => {
this.setState(({ testPayloads }) => ({
testPayloads: [
...testPayloads,
payload as string
]
}))
})
}
render() {
const { testPayloads } = this.state
return testPayloads?.map((payload, index) => (
test-payload-${index}}>{payload}
)) ?? false
}
}
`
$3
return type of BusContext. Maybe, this interface will be deleted if React.ContextType is Emitter, not unknown`.