The field is unregistered when sync error triggered

898 views Asked by At

I have a change password form, in the following structure

<Field name={FORM_FIELDS.OLD_PASSWORD} component={FInputField} type="password" 
validate={[Validation.required]} />
<Field name={FORM_FIELDS.NEW_PASSWORD} component={FInputField} type="password" 
validate={[Validation.required]} />
<Field name={FORM_FIELDS.CONFIRM_PASSWORD} component={FInputField} 
type="password" validate={[ Validation.shouldMatch(password)]} />

and the shouldMatch function

export const shouldMatch = (matchValue) => {
return (value) => {
    return value !== matchValue ? t('common/validationNotMatch') : undefined
}
};

When i input a mismatch in the CONFIRM_PASSWORD field, i got the following actions which is right

{ type: '@@redux-form/UPDATE_SYNC_ERRORS', meta: { form: 'changePassword' }, 
 payload: { syncErrors: { confirmPassword: 'common/validationNotMatch' } } }

but after this action, an UNREGISTER_FIELD action occur, which make the form to clear the sync error object

{ type: '@@redux-form/UNREGISTER_FIELD', meta: { form: 'changePassword' }, 
 payload: { name: 'confirmPassword', destroyOnUnmount: true } }

then the field is registered again

{ type: '@@redux-form/REGISTER_FIELD', meta: { form: 'changePassword' }, 
 payload: { name: 'confirmPassword', type: 'Field' } }

any help, why the UNREGISTER_FIELD action occur here? and how could i make the validation message appear always when there's a mismatch.

1

There are 1 answers

0
jonahe On BEST ANSWER

Reading the docs for the Field prop validate they mention that

Note: if the validate prop changes the field will be re-registered.

I'm thinking that could be the underlying issue. It's not clear from the code you've posted where the password variable in the line Validation.shouldMatch(password) comes from. But for the function to make sense I guess that line will generate a new function each time the password changes. (Ie. the validate prop will change).

But, also from the docs, I read that the signature for the validate prop. is

(value, allValues, props, name) => error [optional]

So it seems you should be able to get the password value from allValues instead, and then you could maybe avoid changing the validate prop. Something like:

export const shouldMatch =  (repeatedPassword, allValues) => {
  const newPassword = allValues[FORM_FIELDS.NEW_PASSWORD];
  return repeatedPassword !== newPassword ? 
     t('common/validationNotMatch') : 
     undefined
};

And use it like

<Field 
 name={FORM_FIELDS.CONFIRM_PASSWORD} 
 component={FInputField} 
 type="password" 
 validate={[ Validation.shouldMatch ]} 
/>