触发同步错误时,该字段未注册

时间:2017-09-14 20:44:11

标签: reactjs redux react-redux redux-form react-redux-form

我有一个更改密码表单,在以下结构中

<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)]} />

和shouldMatch函数

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

当我在CONFIRM_PASSWORD字段中输入不匹配时,我得到了以下正确的操作

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

但在此操作之后,会发生UNREGISTER_FIELD操作,这会使表单清除同步错误对象

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

然后再次注册该字段

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

任何帮助,为什么UNREGISTER_FIELD操作在这里发生?如果出现不匹配的情况,我怎样才能使验证信息显示出来。

1 个答案:

答案 0 :(得分:1)

阅读他们提到的docs for the Field prop validate

  

注意:如果验证道具发生更改,则该字段将重新注册。

我认为这可能是潜在的问题。从您发布的代码中不清楚passwordValidation.shouldMatch(password)中的password变量来自何处。但是为了使函数有意义,我想每次validate更改时该行都会生成一个新函数。 (即验证道具会改变)。

但是,同样来自文档,我读到了password道具的签名。是

  

(value,allValues,props,name)=&gt;错误[可选]

因此,您似乎应该能够从allValues获取validate值,然后您可以避免更改export const shouldMatch = (repeatedPassword, allValues) => { const newPassword = allValues[FORM_FIELDS.NEW_PASSWORD]; return repeatedPassword !== newPassword ? t('common/validationNotMatch') : undefined }; 道具。类似的东西:

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

并像

一样使用它
...setting up everything, until I just need to click on a button...

phantomData    = null;
phantomRequest = null;

// Here, I just recognize the form being submitted and copy it.

casper.on('resource.requested', function(requestData, request) {
    for (var h in requestData.headers) {
        if (requestData.headers[h].name === 'Content-Type') {
            if (requestData.headers[h].value === 'application/x-www-form-urlencoded') {
                phantomData         = requestData;
                phantomRequest      = request;
            }
        }
    }
});

// Here, I recognize when the request has FAILED because PhantomJS does
// not support straight downloading.

casper.on('resource.received', function(resource) {
    for (var h in resource.headers) {
        if (resource.headers[h].name === 'content-disposition') {
            if (resource.stage === 'end') {
                if (phantomData) {
                    // to do: get name from resource.headers[h].value
                    casper.download(
                        resource.url,
                        "output.pdf",
                        phantomData.method,
                        phantomData.postData
                    );
                } else {
                    // Something went wrong.
                }
                // Possibly, remove listeners?
            }
        }
    }
});

// Now, click on the button and initiate the dance.
casper.click(pdfLinkSelector);