我已经开发了React Native应用程序。在这里,我正在通过redux-thunk操作分派来更新状态变量。现在,我想要的是我想在更新后导航到另一个组件。我的写法是这样的。
useEffect(() => {
_navigateOnSuccessOtp(props.navigation);
}, [props.success, props.navigation]);
即使更改了导航,它也会导航到下一个视图,因为它也已作为对此效果的依赖项而添加。这是我完整的组件代码。
import React, {useEffect} from 'react';
import {
View,
TouchableOpacity,
KeyboardAvoidingView,
Switch,
TextInput,
BackHandler,
} from 'react-native';
import I18n from 'react-native-i18n';
import {Formik} from 'formik';
import * as Yup from 'yup';
import {connect} from 'react-redux';
import {signinActions} from '_store/actions';
import SubmitButton from '_components/submitButton/';
import AppText from '_components/appText';
import {strings} from '_translations/i18n';
import styles from './loginstyle';
import Icon from 'react-native-vector-icons/FontAwesome';
const keepMe = (e) => {
console.log(e);
};
const handleBackButton = () => {
return true;
};
const _onPress = (values, sendOTP) => {
console.log(values.mobileNo);
sendOTP(values.mobileNo);
// navigation.navigate('Otp');
};
const _navigateOnSuccessOtp = (navigation) => {
navigation.navigate('Otp');
};
const changeLanguage = (navigate) => {
navigate.navigate('Home');
};
const getCurrentLocale = () => {
let locale;
locale = I18n.locale;
if (locale === 'en') {
return <AppText styles={styles.bottomLinkText}>English</AppText>;
} else if (locale === 'ta') {
return <AppText styles={styles.bottomLinkText}>தமிழ்</AppText>;
}
};
const Login = (props) => {
useEffect(() => {
BackHandler.addEventListener('hardwareBackPress', handleBackButton);
return () => {
BackHandler.removeEventListener('hardwareBackPress', handleBackButton);
};
}, []);
useEffect(() => {
_navigateOnSuccessOtp(props.navigation);
}, [props.success, props.navigation]);
return (
<KeyboardAvoidingView style={{flex: 1}} enabled>
<View style={styles.signinView}>
<View style={styles.signinTitleView}>
<AppText styles={styles.signinTitle}>
{strings('login.title')}
</AppText>
</View>
<View style={styles.colempty} />
<View style={styles.signIn}>
<View style={styles.signInContainer}>
<AppText styles={styles.loginFormTitle}>
{strings('login.title')}
</AppText>
<View style={styles.formContainer}>
<Formik
initialValues={{
mobileNo: '',
toggle: true,
}}
validationSchema={Yup.object({
mobileNo: Yup.string().required('Mobile number required'),
})}
onSubmit={(values, formikActions) => {
_onPress(values, props.sendOTP);
setTimeout(() => {
formikActions.setSubmitting(false);
}, 500);
}}>
{(formprops) => (
<View>
<View
style={
(!formprops.touched.mobileNo
? styles.inputView
: null) ||
(formprops.values.mobileNo && !formprops.errors.mobileNo
? styles.validInputView
: null) ||
(formprops.touched.mobileNo && formprops.errors.mobileNo
? styles.inputViewError
: null)
}>
<TextInput
style={styles.textField}
placeholder={strings('login.mobile')}
placeholderTextColor="#bbbbbb"
value={formprops.values.mobileNo}
onChangeText={formprops.handleChange('mobileNo')}
onBlur={formprops.handleBlur('mobileNo')}
keyboardType="numeric"
/>
{formprops.touched.mobileNo &&
formprops.errors.mobileNo ? (
<Icon name="times" size={20} style={styles.errorIcon} />
) : null}
{formprops.touched.mobileNo &&
formprops.values.mobileNo ? (
<Icon name="check" size={20} style={styles.validIcon} />
) : null}
</View>
{formprops.touched.mobileNo && formprops.errors.mobileNo ? (
<View style={styles.errorMessage}>
<AppText styles={styles.errorMessageText}>
{formprops.errors.mobileNo}
</AppText>
</View>
) : null}
<View style={styles.togglebuttoncontainer}>
<View style={styles.toggleTextView}>
<AppText styles={styles.toggleText}>
{strings('login.keep-login')}
</AppText>
</View>
<View style={styles.toggleView}>
<Switch
trackColor={{false: '#dddddd', true: '#c1d6ee'}}
thumbColor={{false: '#ffffff', true: '#007aff'}}
ios_backgroundColor="#dddddd"
onValueChange={(value) =>
formprops.setFieldValue('toggle', value)
}
value={formprops.values.toggle}
style={styles.toggle}
/>
</View>
</View>
<SubmitButton
onpress={formprops.handleSubmit}
btext={strings('login.button-text')}
/>
</View>
)}
</Formik>
</View>
</View>
</View>
<View style={styles.hr} />
<View style={styles.signInBottomContainer}>
<View style={styles.signInBottomView}>
<View style={styles.signInBottomContainerTextView}>
<AppText styles={styles.signInBottomContainerText}>
{strings('login.language-change')}?
</AppText>
</View>
<View style={styles.signInBottomLinkView}>
<TouchableOpacity
onPress={() => changeLanguage(props.navigation)}>
{getCurrentLocale()}
</TouchableOpacity>
</View>
</View>
</View>
</View>
</KeyboardAvoidingView>
);
};
const mapStateToProps = (state) => {
console.log(state);
return {
success: state.signin.success,
};
};
const mapDispatchToProps = (dispatch) => {
return {
sendOTP: (number) => dispatch(signinActions.sendOtpActionCreator(number)),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Login);
我做了很多尝试以找出正确的方法,但我无法这样做。那么有人可以帮助我解决这个问题吗?谢谢。
Since ,
_navigateOnSuccessOtp
only usesnavigation.navigate
you can simply passprops.navigation.navigate
as a dependency foruseEffect
and also as an argument to the function. Now navigate does not change and hence youruseEffect
won't be triggered unnecessarily.You could also remove props.navigation from the dependency as you don't want useEffect to trigger on props.navigation change. Please check this post for more details: How to fix missing dependency warning when using useEffect React Hook?