Detect window focus change using React
June 07, 2020
- tags:
- en, React /
- Hooks /
- visibilitychange /
I’m contributing one of my friends chat app project and last week I built a toggle that detects if browser window looses or gains its focus. After detecting the focus it was quite easy to add some additional conditionals that decides what is to be rendered on tabs title. So if the window has lost it’s focus check whether there’s new messages from others and if so render a notification emoji etc. to the title.
I wanted to document this handy little technique here that I was able to stumble upon so that it remains on grabs if needed.
Let’s start by creating a new react project to demonstrate.
npx create-react-app test-app
cd test-app
npm start
After that it’s quite simple as well. At the project, inside App
function utilizing Hooks we can create const [isVisible, setIsVisible]
that gets its initial value from document.hidden
.
Note that when using Hooks they of course need to be imported.
import React, { useState, useEffect } from "react";
After state hook creating a helper function const onVisibilityChange = () => setIsVisible(document.hidden);
that sets IsVisible state everytime it’s called.
After that inside useEffect
Effect Hook you can create a event listener that targets window
and takes in "visibilitychange"
as its type and onVisibilityChange
as a listener. This makes sure that the document.hidden
is checked every time there’s a new render and that the isVisible
state is updated accordingly. After that the “used” eventListener is removed in the return.
Here’s the whole code. Also inside useEffect
I set the document.title
to be isVisible
so that the changes in state can be seen in title when toggling between tabs.
import React, { useState, useEffect } from "react";
function App() {
const [isVisible, setIsVisible] = useState();
const onVisibilityChange = () => setIsVisible(document.hidden);
useEffect(() => {
window.addEventListener("visibilitychange", onVisibilityChange);
document.title = isVisible;
return () => {
window.removeEventListener("visibilitychange", onVisibilityChange);
};
});
return (
<div className="App">foo</div>
);
}
export default App;
Lastly I didn’t yet figured out how to manage focus if and when user switches from browser to lets say mail app or Visual Studio Code. With the current example the state does not update even if you have two Chrome browsers open and user toggles between them. Will revisit the topic if/when I manage to figure out how this is done.