如何在触发的onChange事件中引用<input />中的旧值

时间:2018-08-13 13:49:58

标签: javascript reactjs redux

在本质上是一个采访帮助界面上工作,该界面使访问者可以看到问题,向受访者询问问题,设置答案,然后转到下一个问题。

问题在于,实际答案(以数字形式存储)的字段需要使用箭头键进行导航,并且并非所有问题都具有有效答案的简单范围;有时,您可以从1-3、6-9和10、11和12中选择。它表示为“ 1-3,6-9,11,12,13”。 1,2,3和6,7,8,9和11,12,13都是有效选项。 4,5和10不是。 使用箭头键时,产品负责人要求跳过无效的选择。因此,将其从3直接提高到6。

我既没有使用React也没有Redux的经验,所以我不确定该选项在哪里,并且一直在尝试简单地更改该字段的onChange事件触发器。

基本上,它看起来像这样:

<input
  type={input}
  className={`interview-input interview-input-${input}`}
  id="ResponseInput"
  name="response"
  onChange={event => {
    console.log("Prev. value is "+previousValue)
    if (
      item.validate &&
      validateNumeric(event.target.value, item.validate)
    ) {
      dispatch(
        setResponse({
          key: item.key,
          value: event.target.value
        })
      );
    } else if (item.validate &&
      isValueWithinWholeRangeOfRules(event.target.value, item.validate)
    ) {
      dispatch(
        setResponse({
          key: item.key,
          value: selectValueDifferentFromOldValue(
            findClosestViableValueFromInvalidValue(event.target.value,item.validate),
            previousValue
          )
        })
      );
    } else if (!item.validate) {
      dispatch(
        setResponse({
          key: item.key,
          value: event.target.value
        })
      );
    }
  }}
  placeholder={item.validate}
  value={response}
  autoFocus
/>

我想做的是创建一个函数,该函数有助于检测有效值是否至少在最大和最小可能值(isValueWithinWholeRangeOfRules(x,y))的范围内,以便我可以使用( findClosestViableValueFromInvalidValue(x,y))查找2个有效的最近值(例如3和6),然后使用(selectValueDifferentFromOldValue(x,y))进行逻辑运算。 所有帮助程序功能都在这里:

  export const isTextareaInFocus = () =>
  document.activeElement.tagName === 'TEXTAREA';

  // the value provided can be a string or a number
  // rules look like [0-10, 98, 99]
  export const validateNumeric = (value, rules) => {
  let valid = false;
  // allow empty input
  if (value === '') return true;
  rules.forEach(rule => {
    // if the validator contains an interval string (like "0-10") we parse the
    // numbers and check if the value is included in the interval
    if (typeof rule === 'string' && rule.includes('-')) {
      var range = rule.split('-').map(n => parseInt(n, 10));

      if (value >= range[0] && value <= range[1]) {
        valid = true;
      }
    } else if (typeof rule === 'string') {
      if (rule === value.toString()) {
        valid = true;
      }
    } else if (typeof rule === 'number' &&
      (rule === parseInt(value, 10) || rule.toString().includes(value))
    ) {
      // if the rule is a number we check it against the value provided
      valid = true;
    }
  });
  return valid;
  };
  //TODO rename func MRJ
  //Brute forces a search for available options, then entering a non valid value into input; Based on it's own position, it will go high, then low, and then go for the option that it does NOT remember it has been; IE the old value
  export const findClosestViableValueFromInvalidValue = (value, rules) =>{
  var nearest_high = parseInt(value,10);
  var nearest_low = parseInt(value,10);
  while(!validateNumeric(nearest_high,rules))  {
      nearest_high++;
      if (nearest_high>20)
        return false;
  }
  while(!validateNumeric(nearest_low,rules)){
      nearest_low--;
      if (nearest_low<-2)
        return false;
  }
  return [nearest_low,nearest_high];
  };

  export const selectValueDifferentFromOldValue = (values, oldValue)  =>{
  if (oldValue = values[0])
    return values[1];
  else if (oldValue = values[1])
    return values[0];

};

export const isValueWithinWholeRangeOfRules = (value, rules) =>{

  var high=0;
  var low=100;
  rules.forEach(rule => {
    // if the validator contains an interval string (like "0-10") we parse the
    // numbers and check if the value is included in the interval
    if (typeof rule === 'string' && rule.includes('-')) {
      var range = rule.split('-').map(n => parseInt(n, 10));
        if (low > range[0])
          {low = range[0];}
        if (high < range[0])
          {high = range[0];}
        if (low > range[1])
          {low = range[1];}
        if (high < range[1])
          {high = range[1];}
    } else if (typeof rule === 'string') {
        rule === parseInt(value, 10)
        if (low > rule)
          {low = rule;}
        if (high < rule)
          {high = rule;}
    } else if (
      // if the rule is a number we check it against the value provided
      typeof rule === 'number' &&
      (rule === parseInt(value, 10) || rule.toString().includes(value))
    ) {
      if (low > rule)
        {low = rule;}
      if (high < rule)
        {high = rule;}
    }
  });
    value = parseInt(value,10);
    high = parseInt(high,10);
    low = parseInt(low,10);
  if (value >= low && value <= high){
      return true;
    }
  else {
      return false;
    }

  };

item.validate本质上只是一个包含验证要求的字符串(想想Regex,就这么简单)。

实际的问题是,当使用selectValueDifferentFromOldValue时,我需要能够以某种方式引用旧值。但是由于这是在输入字段的onChange事件中发生的,因此已经更改。 (这使我的整个调度设置变得很奇怪,但这是另一回事)。我尝试创建一个全局值来也存储该值,但是同样,onChange会在我将其全局保存之前更改该值,这意味着我必须在更改后保存它,但是这样做会使它超出范围,将它移到1,2,3,然后跳到6,但是保存的全局值为4。

如何可靠地从触发onChange事件之前获取旧值,还是应该找到获取期望结果的其他方法(可以在输入上使用箭头键,跳过无效数字)

0 个答案:

没有答案