首页 > 解决方案 > React.js 如何根据状态显示页面?

问题描述

我想实现一个案例,当用户登录时,他们需要能够访问 AppStack 和 AuthStack。如果他们没有登录,则只能访问 AuthStack。此外,当他们尝试访问 AppStack 时,他们应该被重定向。在本机反应中,我可以使用 AuthStack 来处理这个问题,如果有什么事情改变了用户状态,他可以看到一个堆栈或另一个堆栈。但我不知道如何使用 reactjs

AuthNavigator

import React, { useState, useEffect } from 'react';
import app from './firebase';
import AuthStack from './stacks/AuthStack';
import AppStack from './stacks/AppStack';

function AuthNavigator() {
  const [initializing, setInitializating] = useState(true);
  const [user, setUser] = useState(true);

  function onAuthStateChanged(result) {
    setUser(result);
    if (initializing) setInitializating(false);
    if (result) {
      app
        .auth()
        .currentUser.getIdToken(/* force Refresh */ true)
        .then((idToken) => {
          result.idToken = idToken;
          setUser(result);
        })
        .catch((error) => {
          console.log(error.message);
        });
    }
  }

  useEffect(() => {
    const authSubscriber = app.auth().onAuthStateChanged(onAuthStateChanged);
    return authSubscriber;
  });

  if (initializing) {
    return null;
  }
  return user ? <AppStack user={user} /> : <AuthStack user={user} />;
}
export default AuthNavigator;
AppStack 在这里我尝试过,如果有用户,那么你可以渲染 appStack,否则你会被重定向到 authstack。

import React from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import { Redirect } from 'react-router';
import Overview from '../pages/app/Overview';
import Sidebar from '../components/Sidebar/Sidebar';

function AppStack({ user }) {
  return this.props.user ? (
    <Router>
      <Switch>
        <Sidebar user={user} />
        <Route path="/app-melior/overview" exact component={Overview}></Route>
      </Switch>
    </Router>
  ) : (
    <Redirect path="/auth/signin"></Redirect>
  );
}

export default AppStack;

授权栈

import React from 'react';
import Navbar from '../components/Navbar/Navbar';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import SignIn from '../pages/auth/SignIn';
function AuthStack({ user, app }) {
  return (
    <>
      <Router>
        <Switch>
          <Route path="/auth">
            <Navbar />
            <Route path="/auth/signin" app={app} exact component={SignIn} />
          </Route>
        </Switch>
      </Router>
    </>
  );
}

export default AuthStack;

标签: javascriptreactjs

解决方案


我通常创建一个私有路由并像这样处理它

import React, { useState, useEffect } from 'react';
import app from './firebase';
import AuthStack from './stacks/AuthStack';
import AppStack from './stacks/AppStack';


function AuthNavigator() {
  const [initializing, setInitializating] = useState(true);
  const [user, setUser] = useState(true);

  const PrivateRoute = ({ component, ...rest }) => {
  return (
    <Route
      {...rest}
      render={(props) =>
        user ? (
          <Component {...props}></Component>
        ) : (
          <Redirect to="/auth"></Redirect>
        )
      }
      ></Route>
    );
  };

  function onAuthStateChanged(result) {
    setUser(result);
    if (initializing) setInitializating(false);
    if (result) {
      app
        .auth()
        .currentUser.getIdToken(/* force Refresh */ true)
        .then((idToken) => {
          result.idToken = idToken;
          setUser(result);
        })
        .catch((error) => {
          console.log(error.message);
        });
    }
  }

  useEffect(() => {
    const authSubscriber = app.auth().onAuthStateChanged(onAuthStateChanged);
    return authSubscriber;
  });

  if (initializing) {
    return null;
  }
  return    
    <Router>
      <Switch>
        <PrivateRoute path="/app>
            <Sidebar user={user} />
            <PrivateRoute path="/app-melior/overview" exact component={Overview}></PrivateRoute>
        </PrivateRoute>

        <Route path="/auth">
            <Navbar />
            <Route path="/auth/signin" app={app} exact component={SignIn} />
         </Route>
      </Switch>
    </Router>;
}
export default AuthNavigator;


推荐阅读