1

我正在使用 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;
4

0 回答 0