React Native + Formik:setFieldTouched不起作用

时间:2018-07-05 13:07:48

标签: reactjs react-native redux-saga react-proptypes formik

我正在使用Formik作为React Native的登录屏幕。我遇到了Formik设置“字段接触”为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;

0 个答案:

没有答案