登录后如何在离子反应应用程序中更新侧面菜单项列表

How to update side menu item list in an ionic react app after login

我正在使用 ionic react 创建一个移动应用程序并使用“ionic start --sidemenu”选项。这是我的 App.tsx

<IonApp>
      <IonReactRouter>
        <IonSplitPane contentId="main">
          <Menu isLogged={isLoggedIn} userType={userType} logoutFunc={logout} />
          <IonRouterOutlet id="main">
            <Route path="/user/auth" render={(props) => isLoggedIn ? <Forum {...props} isLoggedIn={isLoggedIn} /> : <AuthHome {...props} />} exact />
            <Route path="/user/register" render={(props) => isLoggedIn ? <Forum {...props} isLoggedIn={isLoggedIn} /> : <Register {...props} />} exact />
            <Route path="/user/register-as-owner" render={(props) => isLoggedIn ? <Forum {...props} isLoggedIn={isLoggedIn} /> : <RegisterAsOwner {...props} />} exact />
            <Route path="/user/login" render={(props) => isLoggedIn ? <Forum {...props} isLoggedIn={isLoggedIn} /> : <Login {...props} />} exact />
            <Route path="/user/profile" render={(props) => <Profile {...props} />} exact />
            <Route path="/user/inbox" render={(props) => <Inbox />} exact />
            <Route path="/user/inbox/:id" render={(props) => <Mail {...props} />} exact />
            <Route path="/user/profile/my-notification" component={MyNotification} exact />
            <Route path='/user/create-team' render={(props) => <CreateTeam {...props} />} exact />
            <Route path='/list-teams' render={props => <TeamListing {...props} />} exact />
            <Route path='/team/:id' render={props => <Team {...props} />} exact />
            <Route path="/forum" component={Forum} exact />
            <Route path="/game" render={(props) => <CreateGameNotification {...props} />} exact />
            <Route path="/game/:id" render={(props) => <GameInfo {...props} />} exact />
            <Route path="/game/comments/:id" render={(props) => <GameComments {...props} />} exact />
            <Redirect from="/" to={isLoggedIn ? "/forum" : "/user/auth"} exact />
            <Redirect from="/user/logout" to="/user/auth" exact />
          </IonRouterOutlet>
        </IonSplitPane>
      </IonReactRouter>
    </IonApp>

这是 Menu.tsx 组件

const getMenuItem = (appPage: AppPage, index: number) => {
    return (
      <IonMenuToggle key={appPage + "-" + index} autoHide={false}>
        <IonItem className={location.pathname === appPage.url ? 'selected' : ''} routerLink={appPage.url} routerDirection="none" lines="none" detail={false}>
          <IonIcon slot="start" ios={appPage.iosIcon} md={appPage.mdIcon} />
          <IonLabel>{appPage.title}</IonLabel>
        </IonItem>
      </IonMenuToggle>
    );
  };

  return (
    <IonMenu contentId="main" type="overlay">
      <IonContent>
        <IonList id="inbox-list">
          <IonListHeader>Menu</IonListHeader>
          {props.isLogged
            ? props.userType == "user"
              ? menuItem.UserMenuPage.map((page: AppPage, i) => getMenuItem(page, i))
              : props.userType == "owner"
                ? menuItem.OwnerMenuPage.map((page: AppPage, i) => getMenuItem(page, i))
                : props.userType == "admin"
                  ? menuItem.AdminMenuPage.map((page: AppPage, i) => getMenuItem(page, i))
                  : <></>
            : menuItem.UnauthenticatedUserMenuPage.map((page: AppPage, i) => getMenuItem(page, i))}
          <IonMenuToggle autoHide={false}>
            <IonItem onClick={e => props.logoutFunc(history)} detail={false}>
              <IonIcon slot="start" ios={personSharp} md={personSharp} />
              <IonLabel>Dil nga profili</IonLabel>
            </IonItem>
          </IonMenuToggle>
        </IonList>
      </IonContent>
    </IonMenu>
  );

当应用程序打开时,它会检查用户是否已经登录,如果没有,它会重定向到登录。登录后,用户将被重定向到论坛页面。


 const [gameList, setGameList] = useState<Game[]>();
    const [unreadMails, setUnreadMails] = useState<number>(0);

    useIonViewWillEnter(() => {
        fetch(env.game_api)
            .then(res => res.json()
                .then(data => {
                    setGameList(data);
                }))
            .catch(err => {
                console.log(err);
            });

        authservice.getUserIdFromStorage()
        .then(id => {
            fetch(env.mail_api + "/user/unread/" + id.value)
            .then(resp => resp.json())
            .then(res => setUnreadMails(res))
            .catch(err => console.log(err));
        });
    });

<IonPage>
            <IonHeader>
                <IonToolbar>
                    <IonButtons slot="start">
                        <IonMenuButton />
                    </IonButtons>
                    <IonTitle color="success">Njoftime</IonTitle>
                    <IonButton onClick={e => props.history.push("/user/inbox")} slot="end" fill="clear">
                        <IonIcon icon={mailOutline} size="large"></IonIcon>
                        {unreadMails > 0 && <IonLabel>{unreadMails}</IonLabel>}
                    </IonButton>
                </IonToolbar>
            </IonHeader>
            <IonContent fullscreen>
                {gameList ? gameList.map((game, i) => {
                    return (
                        <IonCard key={game.title + "-" + i} >
                            <IonCardHeader>
                                <IonCardTitle>
                                    <IonRouterLink href={"/user/profile?user=" + game.posted_by}>
                                        <IonLabel>{game.posted_by_name}</IonLabel>
                                    </IonRouterLink>
                                </IonCardTitle>
                                <IonCardSubtitle>Shkodra Fc</IonCardSubtitle>
                            </IonCardHeader>
                            <IonItem routerLink={"/game/" + game._id} >
                                <IonIcon icon={footballOutline} slot="start" />
                                <IonLabel>Info Mbi ndeshjen</IonLabel>
                            </IonItem>
                            <IonItem lines="none" routerLink={"/game/comments/" + game._id}>
                                <IonIcon icon={chatboxOutline} slot="start" />
                                <IonLabel>Komente te Tjera</IonLabel>
                            </IonItem>
                            
                        </IonCard>
                    )
                }) : <> </>}
            </IonContent>
</IonPage>

根据用户角色,我想显示不同的侧边菜单项,但在用户成功登录后,侧边菜单项不会更新。我必须以何种方式更改我的代码才能使其工作?提前致谢!

那是微不足道的。只需在登录后更新“菜单”页面上“isLogged”的状态即可。

使用状态管理器...但是对于身份验证,我通常使用上下文 API 来保存身份验证状态,然后可以在我的整个应用程序中访问它。

完整的解决方案在这里 Code from state presentation @ Ioniconf,但是当您只粘贴链接时堆栈溢出不喜欢所以这里是一些代码。

我在演示应用程序中也有侧边菜单

import React from "react";

// create the context
export type IAuthContext = {
  authInfo: {
    loggedIn: boolean;
    user: {
      email: string;
      id: string;
    };
  };
  logOut: any;
  logIn: any;
};
const AuthContext = React.createContext<any>(undefined);

// create the context provider, we are using use state to ensure that
// we get reactive values from the context...
export const AuthProvider: React.FC = ({ children }) => {
  // the reactive values
  const [authInfo, setAuthInfo] = React.useState<any>();

  const logOut = () => {
    return new Promise((resolve) => {
      setAuthInfo({ loggedIn: false, user: null });
      setTimeout(() => {
        return resolve(true);
      }, 1000);
    });
  };

  const logIn = (email: string, password: string) => {
    return new Promise((resolve) => {
      let v = {
        loggedIn: true,
        user: { email, id: new Date().getTime() + "" },
      };
      setAuthInfo(v);
      setTimeout(() => {
        return resolve(true);
      }, 1000);
    });
  };

  let v = {
    authInfo,
    logOut: logOut,
    logIn: logIn,
  };

  return <AuthContext.Provider value={v}>{children}</AuthContext.Provider>;
};

export const useAuth = () => React.useContext(AuthContext) as IAuthContext;

用上下文包装应用程序,这是我的 index.tsx

import { AuthProvider } from "./AuthContext";

ReactDOM.render(
  <AuthProvider>
    <App />
  </AuthProvider>,
  document.getElementById("root")
);

现在要使用它,你导入它

import { useAuth } from "../AuthContext";

然后在你的代码访问中,就是方法和属性

const {authInfo} = useAuth();
console.log(authInfo.loggedIn)