Search code examples
redux-form

submit validation destroys form with each render cycle


I'm using RN0.33, redux-form 6.0.5, class decorators and async/await. I'm having problems with submit validation. The form seems to get destroyed and its values are lost.

Let me show you some code.

export async function asyncValidate(action, dispatch, options = {}){

  try{

    dispatch(hideFormException());

    if(!options.hideSpinner)
      dispatch(showSpinner());

    const result = await dispatch(action);

    dbg(result);

    if(Object.keys(result.errors).length > 0){

      throw {validation:result.errors};

    }

    return result;

  }catch(err){

    if(err && err.validation){

      dispatch(showFormException());

      throw new SubmissionError(convertErrors(err.validation));
    }

    exceptionHandler(err,dispatch);

    throw new SubmissionError(err);

  }finally{
    if(!options.hideSpinner)
      dispatch(hideSpinner());
  }
}

Form class

function validate(data){

  const errors = {};

  validation.required(data, 'password', errors)

  validation.email(data, 'username', errors);

  return errors;
}

@reduxForm({
  form: 'login',
  validate: validate,
  onSubmit:(data, dispatch) => formFunctions.asyncValidate(loginUser(data.username, data.password), dispatch)
})
export default class LoginForm extends React.Component {

  constructor(props){
    super(props);

    this.state = {
      showPassword:false
    };

    this.submit = this.submit.bind(this);
    this.showPassword = this.showPassword.bind(this);
  }

  submit(){
    this.props.handleSubmit();
  }

  onSubmitSuccess(){
    this.props.dispatch(initialize('login', {password:null},true));
  }

  field(field){
    return (
      <TextInputField field={field}/>
    );
  }

  render() {

    return (
      <View>
        <View style={stylesheet.cardBody}>

          <Field
            name="username"
            component={this.field}
            placeholder="Email"
            type="text"
            keyboardType="email-address"
            normalize={this.lowerCase}
            />

          <Field
            name="password"
            component={this.field}
            placeholder={getMessage('ui.password')}
            type="password"
            secureTextEntry={!this.state.showPassword}
            />

        </View>

        <View style={stylesheet.cardActions}>
          <View style={stylesheet.btnBox}>
            <FullWidthButton
              onPress={this.submit}
              >
              <Text>{getMessage("ui.login").toUpperCase()}</Text>
            </FullWidthButton>
          </View>
        </View>

      </View>
    );
  }
}

In this case, the action returns an object that looks like this:

{
   errors:[
     {username:'Your username is wrong'} 
   ]
{

What I'm seeing is this: (the first line is the dbg output statement)

enter image description here


Solution

  • So, unless you specify destroyOnUnmount:false in the reduxForm, which is the default, the form will be destroyed if it gets re-rendered (new render cycle). Since these are common occurrences, I don't really get this.