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

时间:2018-01-09 17:23:23

标签: javascript ramda.js

我正在使用热门的reValidation library来验证我的所有输入。我注意到他们使用Ramda来简化所有函数调用。我试图根据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时,我无法获得值输入。使用它的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

下面是一个小小的变化:请注意,二元运算符可能是Ramda部分应用程序的问题。 lte(10)是一个函数,它接受一个值并告诉你10是否小于或等于该值。 (它的完整签名是lte(a, b)返回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

这适用于您的示例吗?

答案 1 :(得分:1)

curry与curmda一起工作的方式是你总是在早期的部分应用程序中指定前面的参数:

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,相当于以下“普通”示例:

(n) => len <= n

在您的情况下,您需要一个函数来告诉您n是否小于或等于len,相当于以下“普通”示例:

(n) => n <= len

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

管理这种情况的一种方法是为函数解释为占位符的第一个参数使用一些特殊值,就像the answer of Scott Sauyet已使用R.__建议的那样占位符。

另一种方法是更改​​函数的参数顺序,以便先提前填写参数。对于二进制函数(2个参数的函数),更改顺序的唯一可能方法是翻转参数。拉姆达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