Home > Software engineering >  How do I return to an existing tab after closing a new tab?
How do I return to an existing tab after closing a new tab?

Time:12-14

How do I redirect my user back to an existing tab?

When a user signs in to my app, I open a new tab (using window.open(url, '_blank')) to contain the signin sequence. After the user completes the signin, I want that tab to close and return to tab that was active before the new tab was opened.

Here is a screenshot of the application when the user is unknown:

unknown startup

When the user clicks the "Signin" button at top right, here is a screenshot showing the second tab (containing the password challenge from Auth0):

password challenge

At the successful conclusion of the signin, here is the placeholder behavior. The Switch complains because I don't know what to do in response to the "continuation" URL:

enter image description here

Here is what the application looks like after a successful signin. I get this by manually refreshing the browser after closing the second tab. Note the Avatar at the top right.

enter image description here

How do I programmatically cause the final screen shot? I want to close the second tab, return to the first tab, and force a render.

I'm lost in the weeds of "window.open" and the behaviors of react-router-dom. My authentication provider is Auth0, and so the application already has a Auth0ProviderWithHistory context as well as a Router around that. That Auth0ProviderWithHistory already has code that's doing something with history:

const history = useHistory();

const onRedirectCallback = (appState) {
  history.push(appState?.returnTo || window.location.pathname);
}

I'm new enough to react-router-dom that I don't really grok what the useHistory and useParams hooks do. At the top of my app, I have a dispatcher that uses Switch and Route to determine the contents that appear in whatever tab is open. The flow through the several signin stages that use the dispatcher seems to work fine. Here is the AppDispatcher that I'm currently using:

import React from 'react';
import {
  Box,
} from '@mui/material';

import { Route, Switch } from 'react-router-dom';
import AppContainer from './AppContainer';
import LoginPersonaContainer from './login_persona/LoginPersonaContainer';
import SigninPersonaContainer from './login_persona/SigninPersonaContainer';
import SuccessContainer from './login_persona/SuccessContainer';
import ClosedContainer from './login_persona/ClosedContainer';

const NoMatch = ({ location }) => (
  <Box>
    <strong>Error!</strong> No route found matching:
    {location.pathname}
  </Box>
);

const AppDispatcher = () => {
  return (
    <Switch>
      <Route
        path="/"
        exact = {true}
        component={AppContainer}
      />
      <Route
        path='/loginPersona/login'
        component = {LoginPersonaContainer}
      />
      <Route
        path='/loginPersona/signin'
        component = {SigninPersonaContainer}
      />
      <Route
        path='/loginPersona/success'
        component = {SuccessContainer}
      />
      <Route
        path='/loginPersona/closed'
        component = {ClosedContainer}
      />
      <Route
        component={NoMatch}
      />
    </Switch>
  );
}

export default AppDispatcher;

I don't see a way to cause the second tab on the browser to close while returning control to the initial tab -- and forcing a render on that tab so that it will reflect the results of the signin.

When the code in the second window just closes the window (window.close), the tab closes but the original window doesn't render. I've tried a variety of alternatives, and they either open a third tab or render the original window's content in the new tab. Neither of those is acceptable.

What react-browser-dom or window incantation causes the "signin" tab to close, return control to the original tab, and force a render/refresh of the original window?

CodePudding user response:

When the second tab loads, You can use

window.opener.document.location.href = "http://localhost:3000"
window.close()

This will go back to the parent tab, and cause it to re-render. Then the second tab will also be closed.

You have to make sure that this code only runs when you visit the route on the second tab

You can find more information about it here https://developer.mozilla.org/en-US/docs/Web/API/Window/opener

  • Related