I'm using formik and yup in react native for a simple login screen. I got 2 forms sign in and signup, one or the other is rendered according to a redux state.
The problem starts when I switch between forms (without touching the form) the initial values does not change. Ex. I'm in LoginForm and then switch to RegisterForm, register form keep { email: '', password: '' } and values from loginform, this is wrong register form should get { firstName: '', surName: '', registerEmail: '', registerPassword: '', acceptTOC: false } .
LoginForm Props
RegisterForm Props after switch
<View style={styles.section}>
{this.props.session.loginForm ? loginFormFormik() : registerForm()}
</View>
Login Form
const loginFormFormik = () => {
return (
<Formik
enableReinitialize={true}
initialValues={{ email: '', password: '' }}
onSubmit={this.onLogInPress}
validationSchema={this.validationSchemaLogin}>
{(formikProps) => {
console.log('TCL: loginFormFormik -> formikProps', formikProps);
const { handleSubmit } = formikProps;
return (
<View>
<View style={[styles.section, styles.sectionStart, styles.loginForm]}>
<InputFormik
formikKey="email"
formikProps={formikProps}
placeholder="Type your account number or email"
label="Username"
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
returnKeyType="next"
onSubmitEditing={() => {
this.loginFormPasswordRef.focus();
}}
/>
<InputFormik
formikKey="password"
formikProps={formikProps}
ref={(child) => {
if (child) {
this.loginFormPasswordRef = child.refProp;
}
}}
placeholder="Type your password"
label="Password"
secureTextEntry={this.state.showPassword}
returnKeyType="go"
containerStyle={inputContainer}
rightIcon={toggleViewIcon}
/>
<ServerError message={this.props.session.loginError} />
<TouchableHighlight
onPress={() => this.props.navigation.navigate('ResetPassword')}
underlayColor={'transparent'}
style={styles.forgotPasswordLinkWrapper}>
<Text style={styles.forgotPasswordLink}>Forgot Password</Text>
</TouchableHighlight>
</View>
<View style={[styles.section, styles.sectionEnd]}>
<SubmitButton handleSubmit={handleSubmit} />
{formSwitchLink()}
</View>
</View>
);
}}
</Formik>
);
};
Register Form
const registerForm = () => {
return (
<Formik
enableReinitialize={true}
initialValues={{
firstName: '',
surName: '',
registerEmail: '',
registerPassword: '',
acceptTOC: false
}}
onSubmit={this.onRegisterPress}
validationSchema={this.validationSchemaRegister}>
{(formikProps) => {
console.log('TCL: registerForm -> formikProps', formikProps);
const { handleSubmit } = formikProps;
return (
<View>
<View style={[styles.section, styles.sectionStart]}>
<InputFormik
formikKey="firstName"
formikProps={formikProps}
placeholder="Type your first name"
label="First name"
keyboardType="default"
autoCapitalize="words"
autoCorrect={false}
returnKeyType="next"
onSubmitEditing={() => {
this.registerFormSurNameRef.focus();
}}
/>
<InputFormik
formikKey="surName"
formikProps={formikProps}
ref={(child) => {
if (child) {
this.registerFormSurNameRef = child.refProp;
}
}}
placeholder="Type your surname"
label="Surname"
keyboardType="default"
autoCapitalize="words"
autoCorrect={false}
returnKeyType="next"
onSubmitEditing={() => {
this.registerFormEmailRef.focus();
}}
/>
<InputFormik
formikKey="registerEmail"
formikProps={formikProps}
ref={(child) => {
if (child) {
this.registerFormEmailRef = child.refProp;
}
}}
placeholder="Type your e-mail address"
label="E-mail"
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
returnKeyType="next"
onSubmitEditing={() => {
this.registerFormPasswordRef.focus();
}}
/>
<InputFormik
formikKey="registerPassword"
formikProps={formikProps}
ref={(child) => {
if (child) {
this.registerFormPasswordRef = child.refProp;
}
}}
placeholder="Type your new password"
label="Password"
secureTextEntry={this.state.showPassword}
returnKeyType="go"
rightIcon={toggleViewIcon}
pwdStrength={true}
/>
<SwitchFormik
label={'Accept Terms & Conditions to use this service.'}
accessibilityLabel="Please accept these terms and conditions"
formikKey="acceptTOC"
formikProps={formikProps}
errorStyle={errorText}
/>
</View>
<ServerError message={this.props.session.registrationError} />
<View style={[styles.section, styles.sectionEnd]}>
<SubmitButton handleSubmit={handleSubmit} />
{formSwitchLink()}
</View>
</View>
);
}}
</Formik>
);
};
InputFormik
class InputFormik extends React.Component {
constructor(props) {
super(props);
this.refProp = React.createRef();
}
render() {
const { formikKey, formikProps, pwdStrength, ...rest } = this.props;
const errorMessage = formikProps.errors[formikKey];
const haveErrors =
formikProps.errors[formikKey] && (formikProps.touched[formikKey] || formikProps.isSubmitting);
return (
<Input
ref={(inputRef) => (this.refProp = inputRef)}
onChangeText={formikProps.handleChange(formikKey)}
onBlur={formikProps.handleBlur(formikKey)}
placeholderTextColor={config.ThemeColors.text.label}
labelStyle={controlLabel.normal}
value={formikProps.values[formikKey]}
errorMessage={haveErrors ? errorMessage : null}
errorProps={{ accessibilityLiveRegion: 'polite' }}
errorStyle={errorText}
inputStyle={haveErrors ? textbox.error : textbox.normal}
inputContainerStyle={haveErrors ? textbox.containerError : null}
containerStyle={inputContainer}
{...rest}
/>
);
}
}
export default InputFormik;