React Native + Formik: setFieldTouched не работает - PullRequest
0 голосов
/ 05 июля 2018

Я использую Formik для экрана входа в React Native. Проблема, с которой я столкнулся при настройке Formik Field Touched на true, хотя я явно установил его на false после запроса входа в систему.

Вот мой код формы:

class LoginForm extends Component {
  static propTypes = {
    navigation: PropTypes.object,
    loginRequest: PropTypes.func,
    isSubmitting: PropTypes.bool
  };

  handleSubmit = (values, formikBag) => {
    this.props.loginRequest(values.email, values.password);
    formikBag.setFieldValue("password", "");
    formikBag.setFieldTouched("password", false, false);
  };

  renderForm = (
    values,
    handleSubmit,
    setFieldValue,
    errors,
    touched,
    setFieldTouched,
    isValid
  ) => (
    <View style={styles.inputContainer}>
      <AuthInput
        placeholder="Email address"
        value={values.email}
        onChange={setFieldValue}
        onTouch={setFieldTouched}
        name="email"
        error={touched.email && errors.email}
        editable={!this.props.isSubmitting}
      />
      <AuthInput
        placeholder="Password"
        value={values.password}
        onChange={setFieldValue}
        onTouch={setFieldTouched}
        name="password"
        error={touched.password && errors.password}
        editable={!this.props.isSubmitting}
        secureTextEntry
      />
      <ClearButton
        text={BUTTON_TEXT_FORGOTTEN_PASSWORD}
        onPress={() => {}}
        containerStyles={styles.clearButtonContainer}
        buttonTextStyles={styles.clearButtonText}
      />
      <Button
        onPress={handleSubmit}
        disabled={!isValid || this.props.isSubmitting}
        loading={this.props.isSubmitting}
      >
        {BUTTON_TEXT_LOGIN}
      </Button>
    </View>
  );

  render() {
    return (
      <Formik
        initialValues={{ email: "", password: "" }}
        onSubmit={this.handleSubmit}
        validationSchema={yupObject().shape({
          email: yupString()
            .email(ERROR_MESSAGE_INVALID_EMAIL_FORMAT)
            .required(ERROR_MESSAGE_EMAIL_REQUIRED),
          password: yupString()
            .min(12, ERROR_MESSAGE_PASSWORD_MIN_LENGTH)
            .required(ERROR_MESSAGE_PASSWORD_REQUIRED)
        })}
        render={({
          values,
          handleSubmit,
          setFieldValue,
          errors,
          touched,
          setFieldTouched,
          isValid
        }) =>
          this.renderForm(
            values,
            handleSubmit,
            setFieldValue,
            errors,
            touched,
            setFieldTouched,
            isValid
          )
        }
      />
    );
  }
}

const mapStateToProps = state => ({
  isSubmitting: state.auth.isSubmitting
});

export default withNavigation(
  connect(
    mapStateToProps,
    { loginRequest }
  )(LoginForm)
);

(Если вам интересно: я не использую значение Formik isSubmitting, потому что мой вход в систему немного сложнее, и я использую для него redux-saga.)

Теперь, если вызван handleSubmit и запрос на вход завершен, значение для пароля корректно стирается. Но также я получаю сообщение об ошибке для требуемого пароля, хотя я явно установил поле, чтобы не трогать. Что я делаю не так?

Я не знаю, имеет ли это какое-либо отношение к этому, но я дополнительно получаю следующее предупреждение:

Warning: Failed prop type: Invalid prop `error` of type `boolean` supplied to `AuthInput`, expected `string`.

Что не имеет смысла, так как мой AuthInput выглядит так:

class AuthInput extends PureComponent {
  handleChange = value => {
    const { onChange, name } = this.props;
    onChange(name, value);
  };

  handleTouch = () => {
    const { onTouch, name } = this.props;
    onTouch(name);
  };

  render() {
    const { placeholder, error } = this.props;
    return (
      <View>
        <TextInput
          autoCapitalize="none"
          autoCorrect={false}
          style={[styles.input, error ? styles.errorInput : null]}
          placeholder={placeholder}
          placeholderTextColor={colors.$lightGrey}
          onChangeText={this.handleChange}
          underlineColorAndroid="transparent"
          onBlur={this.handleTouch}
          {...this.props}
        />
        {error && <Text style={styles.errorText}>{error}</Text>}
      </View>
    );
  }
}

AuthInput.propTypes = {
  placeholder: PropTypes.string,
  name: PropTypes.string,
  error: PropTypes.string,
  onChange: PropTypes.func,
  onTouch: PropTypes.func
};

export default AuthInput;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...