我是React Native的新手,我正在使用Redux创建一个React Native应用程序。我只在登录页面上。目前,我成功实现了redux并在登录凭据正确时从API响应,在凭据错误时得到错误。
基本上,我遇到两个问题。
下面是成功登录后得到的响应
以下是我文件的代码。 屏幕/Login.js
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { FileSelectDirective } from 'ng2-file-upload';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { RegisterLoginComponent } from './register-login/register-login.component';
const routes: Routes = [
{
path: 'products',
component: ProductListComponent
},
{
path: 'product/id',
component: ProductDetailComponent
},
{
path: 'reglogin',
component: RegisterLoginComponent
}
];
@NgModule({
declarations: [
AppComponent,
FileSelectDirective,
ProductListComponent,
ProductDetailComponent,
RegisterLoginComponent
],
imports: [
BrowserModule,
HttpClientModule,
FormsModule,
RouterModule,
RouterModule.forRoot(routes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
actions / user.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));
reducers / 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
})
config / saga.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;
答案 0 :(得分:1)
首先,您需要导入一个提供导航支持的库。
是1。登录成功后如何导航到新屏幕?
答案。选择并整合以下给出的一个库:
问题2。全局存储身份验证令牌的位置,以便我可以识别用户是否在任何页面上登录?
答案。您可以在应用重新启动时使用AsyncStorage来存储和访问用户信息,并决定是导航到主页还是登录屏幕。如果未清除存储(应用未完全关闭),则使用可以使用存储访问经过身份验证的用户
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
中,并在应用程序中的任何位置进行访问。
答案 1 :(得分:0)
使用现有逻辑,您可以在componentWillReceiveProps()
上添加条件。 -
componentWillReceiveProps(nextProps) {
// if (nextProps.loginError && nextProps.loginError !== this.props.loginError) {
if (nextProps.loginError ) {
this.props.alertWithType("error", "Error occurred in login", nextProps.loginError)
}
else if(nextProps.email!=='') {
//this means you have logged in. Your navigation logic will be present here.
}
对于导航,您需要对导航库进行整数化处理,以使this.props.navigation.navigate(...)
正常工作
编辑
如果您希望包含另一个定义用户登录状态的变量,则可以在
之类的componentwillreceiveprops方法中使用它componentWillReceiveProps(nextProps) {
// if (nextProps.loginError && nextProps.loginError !== this.props.loginError) {
if (nextProps.loginError ) {
this.props.alertWithType("error", "Error occurred in login", nextProps.loginError)
}
else if(nextProps.isAuthenticated) {
//this means you have logged in. Your navigation logic will be present here.
}
注意-您必须更新isAuthenticated
的登录成功和登录失败的还原动作,以使其正常运行。