Цель: создать действие, которое возвращает обещание, принимает аргументы и использует диспетчеризацию.
лучшее, что я придумал для действия:
export const loginAction = (arg1, arg2) => {
return (dispatch) => {
dispatch({type: types.SOME_TYPE});
return new Promise((resolve, reject) => {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
loginSuccess(dispatch, user);
resolve(user)
}
}).catch(error => reject(error))
})
}
}
способ, которым я хочу его реализовать:
login = () => {
this.props.loginAction(this.state.email, this.state.password)
.then(user => {
if (user) {
this.props.navigation.navigate("App")
}
}
}
LoginScreen:
import React from 'react';
import { loginUser, logoutUser, resetAuth, sendPwdLink } from '../actions';
import { connect } from 'react-redux';
// other imports...
const { width } = Dimensions.get('window');
class LoginScreen extends React.Component {
constructor (props) {
super(props);
this.state = {
email: '',
password: ''
};
}
goToRegister = () => {
this.props.resetAuth();
this.props.navigation.navigate('Register');
};
goToLearnMore = () => {
this.props.navigation.navigate('LearnMore');
};
login = () => {
this.props.loginUser(this.state.email, this.state.password).then((user) => {
user ? this.props.navigation.navigate('App') : null;
});
};
render () {
return (
<View style={styles.container}>
<View style={{ alignItems: 'center' }}>
<Components.TransparentInput
placeholder={'Email Address...'}
style={{ width: width * 0.5, margin: width * 0.015, fontFamily: Fonts.QUICKSAND }}
placeholderColor={'white'}
onChangeText={(text) => {
this.setState({ email: text });
}}
/>
<Components.TransparentInput
placeholder={'Password...'}
secureTextEntry={true}
style={{ width: width * 0.5, margin: width * 0.015, fontFamily: Fonts.QUICKSAND }}
placeholderColor={'white'}
onChangeText={(text) => {
this.setState({ password: text });
}}
/>
<TouchableWithoutFeedback onPress={() => this.sendPwdLink(this.state.email)}>
<Text
style={{
fontSize: 14,
color: 'white',
textDecorationLine: 'underline',
fontFamily: Fonts.QUICKSAND
}}
>
Forgot password?
</Text>
</TouchableWithoutFeedback>
</View>
<View>
<Components.Button
type={'primary'}
text={'Login'}
onPress={this.login}
style={{ width: width * 0.4, margin: width * 0.015 }}
fontSize={18}
/>
<Components.Button
style={{ width: width * 0.35, margin: width * 0.015 }}
type={'secondary'}
text={'Register'}
onPress={this.goToRegister}
fontSize={18}
/>
</View>
<TouchableWithoutFeedback onPress={this.goToLearnMore}>
<Text
style={{
fontSize: 16,
color: 'white',
textDecorationLine: 'underline',
fontFamily: Fonts.QUICKSAND
}}
>
What is Slide?
</Text>
</TouchableWithoutFeedback>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'space-evenly',
alignItems: 'center',
backgroundColor: Colors.PRIMARY_DARK
}
});
const mapStateToProps = ({ auth }) => {
const { authenticated, loading, error, user } = auth;
return { authenticated, loading, error, user };
};
const mapDispatchToProps = { loginUser, logoutUser, resetAuth, sendPwdLink };
export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen);
Но это не работает, это приводит к ошибке: TypeError: undefined is not an object...evaluating this.props.loginAction(arg1, arg2)
РЕДАКТИРОВАТЬ: я считаю, что действия имеют доступ к dispatch
через функцию mapDispatchToProps. Я могу ошибаться. Я не совсем понимаю эту часть функции действия, но она не работала без нее.
Какие изменения можно внести, чтобы это исправить?