如何替换使用功能组件中的react挂钩进行更新的组件?

时间:2020-05-17 17:17:07

标签: reactjs react-native

我已经开发了React本机应用程序。在这里,我通过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);

我做了很多尝试以找出正确的方法,但是我无法做到。那么有人可以帮助我解决这个问题吗?谢谢。

1 个答案:

答案 0 :(得分:0)

由于,_navigateOnSuccessOtp仅使用navigation.navigate,因此您可以简单地将props.navigation.navigate作为useEffect的依赖项以及函数的参数来传递。现在导航不会更改,因此不会不必要地触发您的useEffect

const _navigateOnSuccessOtp = (navigate) => {
 navigate('Otp');
};

.....

useEffect(() => {
  _navigateOnSuccessOtp(props.navigation.navigate);
}, [props.success, props.navigation.navigate]);

您也可以从依赖项中删除props.navigation,因为您不希望useEffect触发props.navigation更改。请查看此帖子以获取更多详细信息:How to fix missing dependency warning when using useEffect React Hook?