我試圖使用條件性認證流程。
代碼:
return (
<ApolloProvider client={client}>
<NavigationContainer>
<AuthProvider>
<Stack.Navigator>
{userToken ?
// 用戶已經登錄,顯示主螢屏
<Stack.Screen name="Home" component={HomeScreen}。//顯示主螢屏
:
// 沒有找到令牌,用戶沒有登錄,顯示登錄界面
<Stack.Screen
name="SignIn"
component={SignInScreen}
options={{
headerShown: false,
}}
/>
}
</Stack.Navigator>
</AuthProvider>
</NavigationContainer>
</ApolloProvider>
);
}
在兩個螢屏上(首頁,登錄),我都顯示了userToken的狀態,以方便查看是否有變化。
當我登錄時,userToken從null變為token字串,但螢屏停留在SignInScreen上。當我簽出時,userToken從token string變為null,但螢屏始終保持不變。
我不明白為什么不作業了。我讀了很多書,查看了很多例子,但對我來說,所有地方都是一樣的。我找不到有什么不同的地方可以讓它不作業。
有人能幫我解決這個問題嗎?
。親切的問候。 Oskar
編輯。 我從哪里得到userToken
// Auth.tsximport * as React from 'react';
import { getToken, setToken, removeToken } from './utils';
介面 AuthState {
userToken: string | undefined | null;
status: 'idle' | 'signOut' | 'signIn';
type AuthAction = { type: 'SIGN_IN'; token: string } | {型別: 'SIGN_OUT' }。
type AuthPayload = string;
介面 AuthContextActions {
signIn: (data: AuthPayload) => void;
signOut: () => void;
}
介面 AuthContextType 擴展了 AuthState, AuthContextActions {}。
const AuthContext = React.createContext<AuthContextType>({
status: 'idle',
userToken: null,
signIn: () => {},
signOut: () => {},
});
// 以防你想在React樹外使用Auth函式
export const AuthRef = React.createRef<AuthContextActions>()。
export const useAuth = (): AuthContextType => {
const context = React.useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be inside an AuthProvider with a value');
}
return context;
};
export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
const [state, dispatch] = React.useReducer(AuthReducer, {
status: 'idle',
userToken: null,
});
React.useEffect(() => {
const initState = async () => {
try {
const userToken = await getToken();
如果(userToken !== null) {
dispatch({ type: 'SIGN_IN', token: userToken });
} else {
dispatch({ type: 'SIGN_OUT' });
}
} catch (e) {
console.log('initState error ' e)
}
};
initState()。
}, []);
React.useImperativeHandle(AuthRef, () => authActions)。
const authActions: AuthContextActions = React.useMemo(
() => ({
signIn: async (token: string) => {
dispatch({ type: 'SIGN_IN', token });
await setToken(token)。
},
signOut: async () => {
await removeToken(); // TODO: use Vars
dispatch({ type: 'SIGN_OUT' })。
},
}),
[]
);
回傳 (
// <AuthContext.Provider value={{ ...state, ...authActions }}>
<AuthContext.Provider value={{ ...state, ...authActions }}>
{子}
</AuthContext.Provider>
);
};
const AuthReducer = (prevState: AuthState, action: AuthAction): AuthState => {
switch (action.type) {
case 'SIGN_IN':
回傳 {
...prevState。
status: 'signIn',
userToken: action.token,
};
case 'SIGN_OUT':
回傳 {
...prevState。
status: 'signOut',
userToken: null,
};
}
};
uj5u.com熱心網友回復:
嘗試使用一個NavigationContainer用于有符號,一個NavigationContainer用于無符號
看這個例子。https://github.com/akinncar/expo-star-wars/blob/master/src/routes.tsx
uj5u.com熱心網友回復:
另外,你的useEffect是間接依賴于 "userToken "的,它在你的reducer背景關系中。雖然它以迂回的方式獲得了它(await getToken()),但在初始組件加載后它不會再檢查,因為你的空(即[])依賴塊,即:
React.useEffect(() => {
const initState = async ....
initState()。
}, []);
考慮將最后一行改為對你的還原器的用戶令牌狀態的參考,這樣它就會反應性地更新自己,或者其他會產生類似效果的東西。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/315501.html
標籤:
上一篇:如何在Flask的HTTPBasicAuth中引導用戶到登錄頁面而不是登錄彈窗?
下一篇:如何在GitHub上移動分支?
