无法使用 R.path 获取输入值

Unable to get input value using R.path

我用的是流行的reValidation library to validate all my input. I notice they use Ramda to simplify all the function call. I tried to extend their helpers function based on the example。这是我努力实现的目标

import Revalidation from 'revalidation';
import compose from 'ramda/src/compose';
import lte from 'ramda/src/lte';
import path from 'ramda/src/path';

const isValueLTE = len =>
  compose(lte(len), path(['target', 'value']));

const validationRules = {
  quantity: [
    [ isValueLTE(5),
      `Minimum Name length of 5 is required.`
    ],
  ],
};

const Form = ({ revalidation : {form, updateValueAndValidate, updateState, valid, errors = {}, onSubmit} }) =>
  (
  <div className='form'>
    <div className='formGroup'>
      <label>Quantity</label>
      <input
        type='number'
        name="quantity"
        value={form.quantity}
        onChange={updateValueAndValidate}
      />
    </div>
    <button onClick={() => onSubmit(onSubmitCb)}>Submit</button>
  </div>
  )

const EnhancedForm = revalidation(Form);
<EnhancedForm
  initialState={initialState}
  rules={validationRules}
  validateSingle={true}
  validateOnChange={true}
/>

问题是当我使用 compose 包装 ltepath 时无法获取值输入。正确的使用方法是什么?

以下是一个细微的变化:请注意,二元运算符对于 Ramda 的部分应用程序可能是一个问题。 lte(10) 是一个函数,它接受一个值并告诉您 10 是否小于或等于该值。 (它的完整签名是 lte(a, b) returns a <= b,并且正如我提到的那样部分应用了它。但这仍然有些令人惊讶,Ramda 团队从未找到好的解决方案。)所以我们可以写 lte10 = R.lte(R.__, 10),或者更简单地使用 const lte = a => b => b <= a.

const isValueLTE = len => compose(lte(__, len), path(['target', 'value']));

isValueLTE(10)({target: {value: 7}})  //=> true
isValueLTE(10)({target: {value: 15}}) //=> false
isValueLTE(10)({target: {value: 10}}) //=> true

这对您的示例有效吗?

柯里化与 ramda 一起工作的方式是您总是在早期的部分应用程序中指定前一个参数:

lte(1, 2); // returns: true, because 1 is less than or equal to 2
lte(1); // returns something equivalent to: (number) => lte(1, number);

所以如果你调用 lte(len),你会得到一个函数,当它被调用并输入一个数字 n 时,它会告诉你 len 是否小于或等于等于n,相当于下面的'plain'例子:

(n) => len <= n

然而,在您的情况下,您需要一个函数来告诉您 n 是否小于或等于 len,相当于以下 'plain' 示例:

(n) => n <= len

换句话说,您希望使用预先给出的 second 参数部分应用 R.lte。不可能用一个参数调用一个函数,而是将其标记为第二个参数。

处​​理这种情况的一种方法是为函数解释为占位符的第一个参数使用一些特殊值,就像已经建议使用R.__ 占位符。

另一种方法是改变你的函数的参数顺序,让你提前填写的参数排在最前面。对于 binary 函数(具有 2 个参数的函数),更改顺序的唯一可能方法是 flip 参数。 Ramda has a function 为此:

const givenInAdvance = 42;
const isLTE42 = R.flip(R.lte)(givenInAdvance);

这是显式部分应用二元函数的快捷方式,其中第二个参数是预先给出的:

const givenInAdvance = 42;
const isLTE42 = R.lte(R.__, givenInAdvance);

这又等同于手动柯里化 R.lte:

const isLTE42 = (n) => R.lte(n, givenInAdvance)

// equivalent to
const isLTE42 = (n) => n <= givenInAdvance