Handling Unsupported Browser Events in React

Yesterday Ryan Florence released React Network, a component that abstracts away the browser’s detection of network connectivity and accepts two props that are triggered on any change — render, which displays DOM elements, and onChange, which performs a task. Coming in at a compact 33 LOC, I thought it would provide a nice basis to demonstrate handling browser events that are not covered by React’s SyntheticEvent system.

Give it a try on its demo page — it will bring joy to your heart. 🌈

React provides built-in event listening for common user scenarios like scrolling, adding keyboard input, and clicking, but there remain 100-or-so events that must be accessed directly by adding eventListeners. The Network component adds this functionality for the online and offline events, which are triggered when network connectivity changes and the browser toggles the window.navigator.onLine property. When either event is fired, the render and onChange prop callbacks are executed.

Have a look at the code here and let’s take a look at how this component works.

1. Add an event listener when the component mounts

When the component mounts, an eventListener is added for both the offline and online events, each triggering a callback (handleChange) when they are fired. The user’s onChange prop is then run a single time for the current network state.

componentDidMount() {
window.addEventListener("offline", this.handleChange);
window.addEventListener("online", this.handleChange);
this.props.onChange(this.state);
}

When the component is unmounted, the eventListeners are removed:

componentWillUnmount() {
window.removeEventListener("offline", this.handleChange)
window.removeEventListener("online", this.handleChange)
}

2. Define the callback

The handleChange callback is triggered when the user goes online or offline, so it obtains the current network status from the browser, saves it to state, and runs the user’s onChange function.

handleChange = () => {
const online = window.navigator.onLine;
this.props.onChange({ online })
this.setState({ online })
}

The callback does receive the event object, so another option here would be to get the event type from the object rather than the browser. In this case it’s actually more verbose, but it is good to know that the option is there:

handleChange = (e) => {
const online = e.type == 'online' ? true : false;
this.props.onChange({ online })
this.setState({ online })
}

And because the state has been updated, the component calls its render component, which then calls the user’s own render prop.

// The state structure is {online: true}
render() {
return this.props.render(this.state)
}

To summarize, handling unsupported browser events is as simple as manually adding an eventListener when the component is mounted, removing it when it is unmounted, and supplying the eventListener with a callback, which can perform an action and/or update the state.

Show your support

Clapping shows how much you appreciated Yoni Weisbrod’s story.