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