登录后如何在离子反应应用程序中更新侧面菜单项列表
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)
我正在使用 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)