History.push()在注销时重定向到受保护的路由

时间:2019-07-21 21:29:49

标签: reactjs react-router

我正在使用React建立一个基本的身份验证系统,并且在注册和登录操作正确重定向并呈现适当的组件的同时,我的注销操作会重定向到受保护的路由并呈现关联的组件,即使使用注销时上下文API已成功更新。整个操作最终都将完成,因为当我刷新页面时,我已成功重定向到我的登录页面。

我正在使用Node.js来管理我的会话,并且调度注销操作的效果很好,正如我所说的,用于Context API的变量已更新。我在启动注销的Header组件上使用了效果挂钩,并且可以看到auth变量已更改。

这是我的代码:

AppRouter.js

export const history = createBrowserHistory();

const AppRouter = () => (
  <Router history={history}>
    <Switch>
      <PublicRoute path="/" component={AuthPage} exact={true} />
      <PrivateRoute path="/dashboard" component={DashboardPage} />
      <Route component={NotFoundPage} />
    </Switch>
  </Router>
);

PublicRoute.js

const PublicRoute = ({ component: Component, ...rest }) => {

  const { uid } = useContext(AuthContext);

  useEffect(() => {
    console.log("Public Route - Variable set to:", uid);
  }, [uid])

  return (
    <Route
      render={props =>
        uid !== undefined ? (
          <Redirect to="/dashboard" />
        ) : (
          <Component {...props}/>
        )
      }
      {...rest}
    />
  )
};

PrivateRoute.js

const PrivateRoute = ({ component: Component, ...rest }) => {

  const { uid } = useContext(AuthContext);

  useEffect(() => {
    console.log("Private Route - Variable set to:", uid);
  }, [uid])

  return (
    <Route
      render={props =>
        uid !== undefined ? (
          <div>
            <Header />
            <Component {...props}/>
          </div>
        ) : (
          <Redirect to="/" />
        )
      }
      {...rest}
    />
  )
};

Header.js

export const Header = () => {

  const { uid, dispatch } = useContext(AuthContext);

  useEffect(() => {
    console.log("Header - Variable set to:", uid);
    // console.log("HIST", history);
  }, [uid])

  const logout = async () => {

    const result = await startLogout();

    if (result.type !== undefined) {
      dispatch(result); // Works well
      // window.location.href = '/';
      // history.push('/');
      history.replace('/');
    } else {
      console.log(result);
    }
  }

  return (
    <header className="header">
      <div className="container">
        <div className="header__content">
          <Link className="header__title" to="/dashboard">
            <h1>A React App</h1>
          </Link>
          <button className="button button--link" onClick={logout}>Logout</button>
        </div>
      </div>
    </header>
  );
};

我尝试了history.push('/')和history.replace('/')。这两种方法都可以正常工作,就像我将路径切换到未知路由一样,可以成功渲染处理404的组件。

下面是我单击注销按钮时的控制台输出。如您所见,auth变量已很好地更新为 undefined ,但这不会阻止我的路由器继续向我显示受保护的路由。路由器不应该将我重定向到仪表板,因为注销后我的auth变量设置为undefined。

Header - Variable set to: {uid: undefined}
Private Route - Variable set to: {uid: undefined}
Public Route - Variable set to: {uid: undefined}
Header - Variable set to: {uid: undefined}
Private Route - Variable set to: {uid: undefined}

目前,我正在使用效果很好的window.location.href = '/';,因为它会自动重新加载根页面,但我想坚持使用react-router。有什么想法吗?谢谢

1 个答案:

答案 0 :(得分:0)

在私人路线通行证中会呈现道具。

const PrivateRoute = ({ component: Component, ...rest }) => {

  const { uid } = useContext(AuthContext);

  useEffect(() => {
    console.log("Private Route - Variable set to:", uid);
  }, [uid])

  return (
    <Route
      render={props =>
        uid !== undefined ? (
          <div>
            <Header {...props} />
            <Component {...props}/>
          </div>
        ) : (
          <Redirect to="/" />
        )
      }
      {...rest}
    />
  )
};

然后在标头中使用道具推送历史记录:

export const Header = (props) => {

  const { uid, dispatch } = useContext(AuthContext);

  useEffect(() => {
    console.log("Header - Variable set to:", uid);
    // console.log("HIST", history);
  }, [uid])

  const logout = async () => {

    const result = await startLogout();

    if (result.type !== undefined) {
      dispatch(result); // Works well
      // window.location.href = '/';
      // history.push('/');
      props.history.push('/');
    } else {
      console.log(result);
    }
  }