DEV Community

Cover image for How To Logout User From All Tabs At Once In React
Nilesh Kumar
Nilesh Kumar

Posted on

How To Logout User From All Tabs At Once In React

In many React applications, it's common to track changes to state or localStorage values across components, and for this, developers often rely on state management tools like Redux or the Context API. These tools allow you to keep your state in sync within the React component tree. However, a significant challenge arises when you need to update the state from a non-React component (for example, external scripts or browser events). Ensuring that this update is reflected in other React components can be difficult, as it requires careful management of state updates and dispatching actions across different parts of the application.

Managing localstorage in different tab

Tracking localStorage Changes Across Tabs and Active Sessions in React

Managing localStorage in React can be challenging, especially when you need to track changes across different browser tabs or within the same active tab. Imagine having a user logged into your app across multiple tabs—if they log out or update a setting in one tab, wouldn’t it be great to have these changes reflect instantly across all tabs?

  • In this guide, we’ll explore two useEffect examples to handle these cases:

    • Tracking localStorage events in different tabs.
    • Tracking events both across tabs and within the same active tab.

Example 1: Basic Multi-Tab localStorage Event Tracking

Let’s start with the first useEffect, which tracks localStorage changes across multiple tabs. Imagine you have a user logged into several tabs. If they log out in one, you want to log them out everywhere to maintain security.

useEffect(() => {
    const handleStorageChange = (event) => {
      if (event.type === 'storage') {
        const token = localStorage.getItem('token');

        if (!token) {
          cleanLocalStorage();
          setLogin("");
          navigate("/login");
        }
      }
    };

    window.addEventListener('storage', handleStorageChange);

    return () => {
      window.removeEventListener('storage', handleStorageChange);
    };
  }, []);
Enter fullscreen mode Exit fullscreen mode

How This Works:

  • We’re adding an event listener for the storage event, which detects changes in localStorage from other browser tabs.
  • When a user logs out in one tab (removing their token from localStorage), the hook catches this change, and the user is logged out in all other open tabs.

Feature:

  • This hook allows for cross-tab sync, giving a seamless logout experience if the user leaves a tab open and inactive.

Drawback:

  • This only listens to storage events, which means changes made within the same tab (like clearing localStorage) won’t trigger any actions.

Example 2: Advanced Multi-Tab and Same-Tab Syncing

Now, let’s look at an upgraded approach for handling localStorage changes across tabs and within the same active tab. This approach is helpful if your app needs to respond to changes made in the current tab as well.

useEffect(() => {
    const handleStorageChange = (event) => {
      if (event.type === "storage" || event.type === "localStorageChanged") {
        if (skipPath.includes(window.location.pathname)) {
          return;
        }
        const token = localStorage.getItem("token");

        if (!token) {
          dispatch({ type: "LOGOUT" });
          clearData();
          navigate("/login", { replace: true });
        }
      }
    };
    window.addEventListener("storage", handleStorageChange);
    window.addEventListener("localStorageChanged", handleStorageChange);

    return () => {
      window.removeEventListener("storage", handleStorageChange);
      window.removeEventListener("localStorageChanged", handleStorageChange);
    };
  }, []);
Enter fullscreen mode Exit fullscreen mode

To trigger the localStorageChanged event in a non-React component, use the following code when updating localStorage within the same tab. This ensures that changes are properly detected and can be handled accordingly in your application.

window.dispatchEvent(new Event("localStorageChanged"));
Enter fullscreen mode Exit fullscreen mode

How This Works:

  • We add event listeners for both the storage event and a custom event called localStorageChanged.
  • With the custom event, we can trigger handleStorageChange within the same active tab, allowing single-tab changes to also be detected.
  • skipPath provides a way to exclude specific routes from the logout functionality, letting you customise where automatic logout should and shouldn’t happen.

Features:

  • Same-Tab Sync: The custom event, localStorageChanged, lets you detect local changes within the same tab. This can be especially useful for managing user preferences or login sessions.
  • Selective Path Exclusion: By using skipPath, you can exclude specific routes, such as settings or payment pages, from triggering a logout.
  • Cross-Tab Sync: Like the first hook, this one still syncs changes across tabs, ensuring a cohesive user experience.

Drawbacks:

  • Added Complexity: With custom events and path exclusions, managing the code can get a bit more complex, especially if you have many routes or conditional cases.
  • Potential Overhead: Listening to multiple events could slightly impact performance, especially if there are frequent changes to localStorage.

Real-World Example: Secure, Seamless Logout

Think of a social media app open in several tabs. A user logs out in one tab, and all tabs should log them out immediately to prevent security risks. Similarly, if they’re on a secure settings page, you may want to avoid sudden logouts by excluding this route.

With these hooks, you can:

  • Automatically log the user out of all tabs when they log out in one.
  • Avoid logging them out unexpectedly from certain pages.
  • Detect changes in both multi-tab and single-tab contexts for a smoother experience.

Final Thoughts

Tracking localStorage events across tabs and within the same active session can significantly enhance user experience, especially for multi-tab security and state consistency.

Both useEffect hooks work together without interfering with each other, allowing for both cross-tab and single-tab functionality. Whether it’s a logout action or a user setting change, this approach ensures users see an up-to-date, consistent experience across your entire app.

By understanding and combining these approaches, you can make your app feel more responsive and secure for users, adapting dynamically to user actions across tabs and sessions.

Top comments (0)