每次 React Native Expo App 刷新时获取注销?
Getting LogOut everytime React Native Expo App refreshes?
我是 React Native 的新手,正在使用 Expo 并尝试使用 AuthContext 和 AsyncStorage 登录,登录后它会将我带到 HomeScreen 。但是当我对组件进行更改时,它会刷新应用程序并从应用程序中注销我。每次我做一些更改,我都需要重新登录。
任何人都可以帮助我哪里出错了。我现在使用 AsyncStorage 来提供离线支持和减速器。
App.js
<AuthContext.Provider value={authContext}>
<NavigationContainer>
{ loginState.userToken != null ? (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={PreNav}/>
<Drawer.Screen name="Support" component={SupportScreen}/>
<Drawer.Screen name="Settings" component={SettingsScreen}></Drawer.Screen>
</Drawer.Navigator>
): <RootStackScreen />
}
</NavigationContainer>
</AuthContext.Provider>
const initialLoginState = {
isLoading: true,
userName: null,
userToken: null,
}
const loginReducer = (prevState, action) => {
switch(action.type) {
case 'RETRIEVE_TOKEN':
return {
...prevState,
userToken: action.token,
isLoading: false
};
case 'LOGIN':
return {
...prevState,
userName: action.id,
userToken: action.token,
isLoading: false
};
case 'LOGOUT':
return {
...prevState,
userName: null,
userToken: null,
isLoading: false
};
case 'REGISTER':
return {
...prevState,
userName: action.id,
userToken: action.token,
isLoading: false
};
}
}
const [loginState, dispatch] = useReducer(loginReducer, initialLoginState)
const authContext = useMemo(() => ({
userLogin: async (userName, password) => {
// setUserToken("abc");
// setLoading(false);
let userToken;
userToken = 'abc';
if (userName == 'user' && password == 'pass') {
try {
await AsyncStorage.setItem('userToken', userToken)
}
catch(e) {
console.log(e);
}
}
dispatch({type: 'LOGIN', id: userName, token: userToken});
},
userSignup: () => {
},
}));
useEffect(() => {
setTimeout(async () => {
// setLoading(false);
let userToken;
try {
await AsyncStorage.getItem('userToken')
}
catch(e) {
console.log(e);
}
dispatch({type: 'RETRIEVE_TOKEN', token: userToken});
}, 1000);
}, []);
LoginScreen.js
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [pwd, resetPwd] = useState(false);
const { userLogin } = useContext(AuthContext);
return(
<KeyboardAvoidingView behavior='position'>
<View style={styles.logoView}>
<Image style={styles.loginImage} source={require('../assets/login.png')}/>
<View>
<Text style={styles.logoText}> Welcome </Text>
<Text style={styles.logoSubText}> Please Login to continue, If account already created. </Text>
</View>
</View>
<View style={styles.loginInput}>
<Input placeholder='Enter your email address' value={email} onChangeText={(email) => setEmail(email)}
leftIcon={<IconI name='email' size={24} color='black' />}/>
<Input placeholder='Enter your password' secureTextEntry={true} value={password} onChangeText={(password) => {setPassword(password)}}
leftIcon={<Icon name='key' size={24} color='black' />}/>
</View>
<View style={styles.loginButtonBox}>
<TouchableOpacity onPress={() => userLogin(email, password)}>
<Text style={styles.loginButton}> LOGIN </Text>
</TouchableOpacity>
</View>
<View style={styles.noAccount}>
<Text>{"\n"} Don't have an account yet ? </Text>
<TouchableOpacity onPress={() => navigation.navigate('SignupScreen')}>
<Text style={styles.linkText}>{"\n"} Create New One </Text>
</TouchableOpacity>
</View>
<View style={styles.forgotPassword}>
<Text>{"\n"} Don't remember the Password ? </Text>
<TouchableOpacity style={styles.linkText} onPress={() => {
resetPwd(true);
}}>
<Text style={styles.linkText}>{"\n"} Forgot Password </Text>
</TouchableOpacity>
</View>
context.js
export const AuthContext = createContext();
根据您提供的代码观察,
这是问题,由于使用 RETRIVE_TOKEN 操作保存 userToken 无法正常工作,因为代码行为尚未将 userToken 变量初始化为从异步存储获取的值,因此,您必须使用从 asyncStorage 获取的值初始化 userToken 变量。
您可以尝试在您的 App.js useEffect 挂钩中更改以下代码
useEffect(() => {
setTimeout(async () => {
let userToken;
try {
userToken = await AsyncStorage.getItem('userToken')
}
catch(e) {
console.log(e);
}
dispatch({type: 'RETRIEVE_TOKEN', token: userToken});
}, 1000);
}, []);
我是 React Native 的新手,正在使用 Expo 并尝试使用 AuthContext 和 AsyncStorage 登录,登录后它会将我带到 HomeScreen 。但是当我对组件进行更改时,它会刷新应用程序并从应用程序中注销我。每次我做一些更改,我都需要重新登录。
任何人都可以帮助我哪里出错了。我现在使用 AsyncStorage 来提供离线支持和减速器。
App.js
<AuthContext.Provider value={authContext}>
<NavigationContainer>
{ loginState.userToken != null ? (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={PreNav}/>
<Drawer.Screen name="Support" component={SupportScreen}/>
<Drawer.Screen name="Settings" component={SettingsScreen}></Drawer.Screen>
</Drawer.Navigator>
): <RootStackScreen />
}
</NavigationContainer>
</AuthContext.Provider>
const initialLoginState = {
isLoading: true,
userName: null,
userToken: null,
}
const loginReducer = (prevState, action) => {
switch(action.type) {
case 'RETRIEVE_TOKEN':
return {
...prevState,
userToken: action.token,
isLoading: false
};
case 'LOGIN':
return {
...prevState,
userName: action.id,
userToken: action.token,
isLoading: false
};
case 'LOGOUT':
return {
...prevState,
userName: null,
userToken: null,
isLoading: false
};
case 'REGISTER':
return {
...prevState,
userName: action.id,
userToken: action.token,
isLoading: false
};
}
}
const [loginState, dispatch] = useReducer(loginReducer, initialLoginState)
const authContext = useMemo(() => ({
userLogin: async (userName, password) => {
// setUserToken("abc");
// setLoading(false);
let userToken;
userToken = 'abc';
if (userName == 'user' && password == 'pass') {
try {
await AsyncStorage.setItem('userToken', userToken)
}
catch(e) {
console.log(e);
}
}
dispatch({type: 'LOGIN', id: userName, token: userToken});
},
userSignup: () => {
},
}));
useEffect(() => {
setTimeout(async () => {
// setLoading(false);
let userToken;
try {
await AsyncStorage.getItem('userToken')
}
catch(e) {
console.log(e);
}
dispatch({type: 'RETRIEVE_TOKEN', token: userToken});
}, 1000);
}, []);
LoginScreen.js
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [pwd, resetPwd] = useState(false);
const { userLogin } = useContext(AuthContext);
return(
<KeyboardAvoidingView behavior='position'>
<View style={styles.logoView}>
<Image style={styles.loginImage} source={require('../assets/login.png')}/>
<View>
<Text style={styles.logoText}> Welcome </Text>
<Text style={styles.logoSubText}> Please Login to continue, If account already created. </Text>
</View>
</View>
<View style={styles.loginInput}>
<Input placeholder='Enter your email address' value={email} onChangeText={(email) => setEmail(email)}
leftIcon={<IconI name='email' size={24} color='black' />}/>
<Input placeholder='Enter your password' secureTextEntry={true} value={password} onChangeText={(password) => {setPassword(password)}}
leftIcon={<Icon name='key' size={24} color='black' />}/>
</View>
<View style={styles.loginButtonBox}>
<TouchableOpacity onPress={() => userLogin(email, password)}>
<Text style={styles.loginButton}> LOGIN </Text>
</TouchableOpacity>
</View>
<View style={styles.noAccount}>
<Text>{"\n"} Don't have an account yet ? </Text>
<TouchableOpacity onPress={() => navigation.navigate('SignupScreen')}>
<Text style={styles.linkText}>{"\n"} Create New One </Text>
</TouchableOpacity>
</View>
<View style={styles.forgotPassword}>
<Text>{"\n"} Don't remember the Password ? </Text>
<TouchableOpacity style={styles.linkText} onPress={() => {
resetPwd(true);
}}>
<Text style={styles.linkText}>{"\n"} Forgot Password </Text>
</TouchableOpacity>
</View>
context.js
export const AuthContext = createContext();
根据您提供的代码观察,
这是问题,由于使用 RETRIVE_TOKEN 操作保存 userToken 无法正常工作,因为代码行为尚未将 userToken 变量初始化为从异步存储获取的值,因此,您必须使用从 asyncStorage 获取的值初始化 userToken 变量。
您可以尝试在您的 App.js useEffect 挂钩中更改以下代码
useEffect(() => {
setTimeout(async () => {
let userToken;
try {
userToken = await AsyncStorage.getItem('userToken')
}
catch(e) {
console.log(e);
}
dispatch({type: 'RETRIEVE_TOKEN', token: userToken});
}, 1000);
}, []);