【发布时间】:2019-11-10 08:25:22
【问题描述】:
我正在使用react-native、redux 和react-navigation 构建一个移动应用程序。
我一直在考虑哪个代码应该有一个关于屏幕转换的功能(例如this.props.navigation.navigate('NextScreen'))。
例如,在我的应用中,登录过程如下。
如您所见,应用程序在登录屏幕的 handleSignIn 函数中运行 this.props.navigation.navigate()。
[问题]
- 状态中的
uid值有时为空,如果用户登录成功则应填写,但有时不填写。我该如何解决? -
this.props.navigator.navigator()在screen组件中定义的函数中执行,好不好?
有我的代码。
- 登录屏幕
import React, { Component } from 'react';
import { ActivityIndicator, Keyboard, KeyboardAvoidingView, StyleSheet } from 'react-native';
import { connect } from 'react-redux';
:
class SignIn extends Component {
async handleSignIn() {
const { navigation, requestSignIn } = this.props;
const { uid, email, password, error } = this.props.auth;
Keyboard.dismiss();
requestSignIn(email, password);
// sometimes this uid is blank
if (uid) {
alert('success');
// this function should be executed here?
navigation.navigate('Match', { uid: uid });
} else {
alert(error);
}
}
render() {
const { navigation, changeText } = this.props;
const { email, password, loading } = this.props.auth;
return (
:
<Button gradient onPress={() => this.handleSignIn()}>
{ loading ?
<ActivityIndicator size='small' color='white' /> :
<Text bold white center>Sign In</Text>
}
</Button>
:
)
}
}
const mapStateToProps = state => {
return {
auth: state.auth
}
};
const mapDispatchToProps = dispatch => {
return {
requestSignIn: (email, password) => dispatch(auth.requestSignIn(email, password)),
}
};
export default connect(mapStateToProps, mapDispatchToProps)(SignIn);
:
- 动作
:
export const REQUEST_SIGN_IN_SUCCESS = 'REQUEST_SIGN_IN_SUCCESS';
export const REQUEST_SIGN_IN_FAILURE = 'REQUEST_SIGN_IN_FAILURE';
export function requestSignIn(email, password) {
return async function (dispatch) {
// change loading status
dispatch(startedRequest());
if (email && password) {
await firebase.auth().signInWithEmailAndPassword(email, password)
.then(response => {
if (response) {
// save email and password in local secure storage.
SecureStorage.setItem('email', email);
SecureStorage.setItem('password', password);
dispatch(requestSignInSuccess(response.user.uid))
} else {
return Promise.resolve(new Error(response));
}
})
.catch(error => {
switch (error.code) {
case 'auth/user-not-found':
dispatch(requestSignInFailure('user not found'));
break;
case 'auth/invalid-email':
dispatch(requestSignInFailure('invalid email'));
break;
default:
dispatch(requestSignInFailure('something went wrong'))
}
})
} else {
dispatch(requestSignInFailure('error message from else statement'))
}
}
}
export function requestSignInSuccess(uid) {
return {
type: REQUEST_SIGN_IN_SUCCESS,
payload: {
uid: uid
}
}
}
export function requestSignInFailure(errorMessage) {
return {
type: REQUEST_SIGN_IN_FAILURE,
payload: {
errorMessage: errorMessage
}
}
}
- 减速机
import * as ActionType from '../actions/auth';
const initialState = {
uid: '',
email: '',
password: '',
isLoading: false,
error: {
message: ''
}
};
const auth = (state=initialState, action) => {
const { type, payload } = action;
switch (type) {
case ActionType.STARTED_REQUEST:
return Object.assign({}, state, {
isLoading: true
});
case ActionType.CHANGE_TEXT:
return Object.assign({}, state, {
[payload.key]: payload.value
});
case ActionType.REQUEST_SIGN_IN_SUCCESS:
return Object.assign({}, state, {
uid: payload.uid,
isLoading: false,
});
case ActionType.REQUEST_SIGN_IN_FAILURE:
return Object.assign({}, state, {
isLoading: false,
error: {
message: payload.errorMessage,
},
});
default:
return { ...state };
}
};
export default auth;
【问题讨论】:
标签: react-native redux react-navigation