react-native - React Native - 登录后如何存储身份验证令牌并导航到其他屏幕?
问题描述
我是 react native 的新手,我正在使用 redux 创建一个 react native 应用程序。我只在登录页面上。目前,我成功实现了 redux,并在登录凭据正确时从 API 获得响应,如果凭据错误则得到错误。
基本上,我有两个问题被困在其中。
- 登录成功后如何导航到新屏幕?
- 在哪里全局存储身份验证令牌,以便我可以识别用户是否在任何页面上登录?
以下是我登录成功时得到的响应
以下是我的文件的代码。屏幕/登录.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { LoginComponent } from '../components/LoginComponent';
// import { Button } from 'react-native-material-design';
import { View, Text, TextInput, StatusBar, KeyboardAvoidingView } from 'react-native';
import { Button } from 'react-native-elements';
import PropTypes from 'prop-types';
import { connectAlert } from '../components/Alert';
import { login, handleEmailChange, handlePasswordChange } from '../actions/user';
class Login extends Component {
static propTypes = {
navigation: PropTypes.object,
// dispatch: PropTypes.func,
user: PropTypes.object,
email: PropTypes.string,
password: PropTypes.string,
alertWithType: PropTypes.func,
loginError: PropTypes.string
}
componentWillReceiveProps(nextProps) {
// if (nextProps.loginError && nextProps.loginError !== this.props.loginError) {
if (nextProps.loginError ) {
this.props.alertWithType("error", "Error occurred in login", nextProps.loginError)
}
}
handleSubmit = () => {
this.props.login(this.props.email, this.props.password)
}
handleChange = (type, e) => {
if (type === "email"){
this.props.dispatch(handleEmailChange(e))
}
else{
this.props.dispatch(handlePasswordChange(e))
}
}
render(){
return(
<View style={{ flex: 1, justifyContent: 'center' }}>
<StatusBar barStyle="default" translucent={false} />
<KeyboardAvoidingView behavior='padding'>
<Text style={{textAlign: 'center', fontWeight: '800'}}> AfterClix Login </Text>
<TextInput
autoCapitalize="none"
onSubmitEditing={() => this.passwordInput.focus()}
autoCorrect={false}
keyboardType='email-address'
returnKeyType="next"
placeholder='Email'
// onChangeText={event => this.handleChange("email",event)}
onChangeText={this.props.changeEmailValue}
placeholderTextColor='rgb(65, 146, 244)'/>
<TextInput
returnKeyType="go"
ref={(input)=> this.passwordInput = input}
placeholder='Password'
placeholderTextColor='rgb(65, 146, 244)'
onChangeText={this.props.changePasswordValue}
// onChangeText={event => this.handleChange("password",event)}
secureTextEntry/>
<Button raised title="Login" backgroundColor="rgb(65, 146, 244)" color="#FFFFFF" onPress={this.handleSubmit}/>
</KeyboardAvoidingView>
</View>
)
}
}
const mapStateToProps = (state) => {
return {
// user: state.authentication.user
email: state.user.email,
password: state.user.password,
loginError: state.user.error
}
}
const mapDispatchToProps = dispatch => {
return {
changeEmailValue: (text) => dispatch({type: 'CHANGE_EMAIL_VALUE', text}),
changePasswordValue: (text) => dispatch({type: 'CHANGE_PASSWORD_VALUE', text}),
login: (email,password) => dispatch({type: 'LOGIN', email, password}),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(connectAlert(Login));
动作/user.js
export const LOGIN = "LOGIN";
export const AUTHENTICATION_RESULT = "AUTHENTICATION_RESULT";
export const AUTHENTICATION_ERROR = "AUTHENTICATION_ERROR";
export const CHANGE_EMAIL_VALUE = "CHANGE_EMAIL_VALUE";
export const CHANGE_PASSWORD_VALUE = "CHANGE_PASSWORD_VALUE";
export const login = (email, password) => ({
type: LOGIN,
email: email,
password: password
})
export const handleEmailChange = (value) => ({
type: CHANGE_EMAIL_VALUE,
email: value
})
export const handlePasswordChange = (value) => ({
type: CHANGE_PASSWORD_VALUE,
password: value
})
减速器/user.js
import {LOGIN, AUTHENTICATION_RESULT, AUTHENTICATION_ERROR, CHANGE_EMAIL_VALUE, CHANGE_PASSWORD_VALUE} from '../actions/user'
const initialState = {
// user: {
// email: '',
// password: '',
// error: null,
// }
email: '',
password: '',
error: null,
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case LOGIN:
return {
...state,
email: state.email,
password: state.password
}
case CHANGE_EMAIL_VALUE:
// return {...state, email: action.email };
return {...state, email: action.text };
case CHANGE_PASSWORD_VALUE:
return {...state, password: action.text };
case AUTHENTICATION_RESULT:
console.log("Result", action.result.data)
return {...state, email: action.result.data.user.email, password: action.result.data.user.password };
// return {
// ...state,
// user: {
// ...state,
// [action.result.base]: {
// ...action.result,
// }
// }
// }
case AUTHENTICATION_ERROR:
return {
...state,
error: action.error,
}
default:
return state;
}
}
export default reducer;
配置/传奇.js
import { takeEvery, select, call, put } from 'redux-saga/effects';
import { LOGIN, AUTHENTICATION_RESULT, AUTHENTICATION_ERROR } from '../actions/user';
const authenticateUser = (email, password) => fetch('apiURL/oauth/token', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
password: password,
grant_type: "password"
}),
});
function* fetchUser(action){
try{
console.log("Email", action.email)
console.log("Password", action.password)
const response = yield call(authenticateUser, action.email, action.password)
const result = yield response.json();
if (result.error) {
yield put({ type: AUTHENTICATION_ERROR, error: result.error });
} else {
yield put({ type: AUTHENTICATION_RESULT, result });
}
}
catch (e) {
yield put({ type: AUTHENTICATION_ERROR, error: e.message });
}
}
export default function* rootSaga() {
yield takeEvery(LOGIN, fetchUser);
}
解决方案
首先,您需要导入一个提供导航支持的库。
问题 1.登录成功后如何跳转到新界面?
回答。选择并集成下面给出的库之一:
问题 2.在哪里全局存储身份验证令牌,以便我可以识别用户是否在任何页面上登录?
回答。您可以使用AsyncStorage在应用重新启动时存储和访问用户信息,并决定是导航到主屏幕还是登录屏幕。当 store 未清空时(app 未完全关闭),则可以使用 store 访问认证用户
yield setItem('user', JSON.stringify(result.user)); // save user in asyncStorage - permanent
yield put({ type: AUTHENTICATION_RESULT, result }); // save user in store - temporary
yield put(NavigationActions.navigate({ routeName: 'drawerStack' })); //and then navigate to home
const setItem = async (name, data) => {
try {
await AsyncStorage.setItem(name, JSON.stringify(data));
console.log('data stored');
} catch (error) {
// Error saving data
console.log('AsyncStorage save error: ' + error.message);
}
};
您可以将结果存储在应用程序的任何位置,store
也AsyncStorage
可以在任何位置访问它。
推荐阅读
- python - 使用循环在 Python 中导入、重命名和合并 Excel 工作表
- python-3.x - 带有自定义评估函数的 Python 中 xgboost 的意外行为
- git - 继承计算机 - 未找到存储库
- testing - 如何使用 Elixir 测试 Web 服务?
- php - 从列中选择一个值并获取相对于 php 中所选值的其他值
- python - 将数据保存在文件python中
- ios - 来自 TestFlight 的更新是否与来自 Appstore 的更新相同
- python - 使用Python将数据框以数据框名称作为文件名写入excel
- r - 在 R 中安装包时出错:.rs.Env
- c - 使用交叉编译器运行 Makefile 时出错