不确定函数的作用:语法

Uncertain about what the function does: syntax

export const composeValidators = (...validators) => value => validators.reduce((error, validator) => error || validator(value), undefined);

我不确定上面代码的语法。有人可以帮我分解一下吗?

我是箭头函数的新手,但我在这里看到了多个!!!该函数在 redux-final-form 验证器字段上被调用。我该如何更改它,使其 returns 未定义,表示没有验证失败和 '!验证失败的验证消息。

我想知道是否可以制作一个 newComposeValidators 函数,将相同的参数传递给 composeValidators 函数,并且 returns 错误消息前面加上感叹号和 space?

它的用法如下:

Field name="postalCode" validate={composeValidators(requiredValidator, postalCodeValidator)}>
                  {({ input, meta }) => (
                    <Fragment>
                      <StyledInput
                        validationFailed={meta.touched && meta.error}
                        placeholder={postalCodePlaceholder}
                        required
                        {...input}
                      />
                      <StyledFieldError meta={meta} />
                    </Fragment>
                  )}
                </Field>

验证器定义为:

  const messages = {
  required: 'Input is required',
  email: 'Invalid Email',
  phone: 'Invalid Phone Number',
  postalCode: 'Invalid Postal Code',
  positiveNumber: 'Must be greater than 0',
  pastDate: 'Please enter a valid date in the past',
};

const requiredValidator = (value) => (value && value.trim().length ? undefined : messages.required);
const emailValidator = (value) => (!value || emailRegex.test(value) ? undefined : messages.email);
const phoneValidator = (value) => (!value || phoneNumberRegex.test(value) ? undefined : messages.phone);
const postalCodeValidator = (value) =>
  !value || zipCodeRegex.test(value) || canadianPostalCodeRegex.test(value) ? undefined : messages.postalCode;
const positiveNumberValidator = (value) =>
  value && Number.isInteger(+value) && +value > 0 ? undefined : messages.positiveNumber;
const pastDateValidator = (value) => {
  if (!value || !dateRegex.test(value)) {
    return messages.pastDate;
  }
export const composeValidators = (...validators) => value => validators.reduce((error, validator) => error || validator(value), undefined)

此函数将验证器函数数组作为参数,return 另一个函数。

returned 函数将您的值作为参数,然后通过验证器函数进行映射, if validator(value) return value then error is assigned to that value 依此类推(undefined 是 error 的初始值),然后 return error

看看reduce函数

您的函数可能如下所示

export const composeValidators = (...validators) => {
  return function checkError(value){
    // validators = [ requiredValidator, postalCodeValidator ] in this case    
    // imaginevalidators.reduce((error, validator) => error || validator(value), undefined) does something like this
    let error = undefined
    validators.map(validator => { // loop through array of validator function
      if(validator(value)) {
        error = validator(value)
      }
    })
    return error
  }
}

追加!如果验证失败 space 则出错

validators.reduce((error, validator) => error || `! ${validator(value)}`, undefined)

我认为最好的解释方式是通过一个例子。所以给出这个函数:

export const composeValidators = (...validators) => value => validators.reduce((error, validator) => error || validator(value), undefined)

我们可以这样称呼它:

composeValidators(valiadationRuleFunction1, valiadationRuleFunction2)( 'someValueHere')

所以 (...validators) 变成 [valiadationRuleFunction1, valiadationRuleFunction2]'someValueHere' 变成 value.


而言
validators.reduce((error, validator) => error || validator(value), undefined)

我们首先将 'error' 定义为未定义的值。第一次运行时,错误将是未定义的,因此它将使用提供的值调用 valiadationRuleFunction1,即 valiadationRuleFunction1('someValueHere').

如果通过验证,'error' 仍将是未定义的,因此 valiadationRuleFunction2 将使用提供的相同值被调用,即 valiadationRuleFunction2('someValueHere').

当前函数在遇到错误时会短路,即如果 valiadationRuleFunction1('someValueHere') 是 return 验证错误 - 那么 'error' 现在将被定义。 当我们执行此检查时 error || validator(value) - 错误将被 returned 并且 valiadationRuleFunction2('someValueHere) 将不会被执行。

这适用于基于优先级显示的单个错误消息,即最重要的验证规则应首先传递给 'composeValidators'。 如果存在需要显示多个错误消息的场景,我们会将 reduce 函数中的默认 'error' 值从 'undefined' 更改为 '[]'。每次验证器运行并且 return 出现错误时 - 我们会将此错误推送到数组和 return 错误数组。


正在测试这个 return 函数

鉴于我们有一个验证器(这将 return 当未指定值时出错,即需要验证):

export const valiadationRuleFunction1 = value => !value ? 'Please provide a value' : undefined`
  1. 使用 * 语法导入此规则,即 import * as ValidationRules from './pathToWhereThisRuleLives'
  2. 为此验证规则创建间谍,例如const valiadationRuleFunction1Spy = jest.spyOn(Validation,'valiadationRuleFunction1');
  3. 使用验证器和一个将触发错误的值调用 'composeValidators' 函数并断言错误消息 returned 即 expect(composeValidators(valiadationRuleFunction1)('')).toBe('Please provide a value');
  4. 然后我们可以使用 valiadationRuleFunction1Spy 断言调用了实际的验证函数,即 expect(valiadationRuleFunction1Spy).toHaveBeenCalledTimes(1);