javascript 如何将React输入字段限制为父最小和最大props?

lrpiutwd  于 2023-05-27  发布在  Java
关注(0)|答案(3)|浏览(88)

我对这里的React很陌生。我尝试将输入限制为min-10和max 10。我有它,所以输入可以接受输入,我试图使用钩子useState和useEffect来尝试更改和设置输入中的值。无论输入中有什么,当你点击它时,它都应该被限制为-10或10。我知道有onBlur来触发一个函数或状态,但我不知道从那里去哪里。任何帮助都将不胜感激。

// For reference, this component is rendered
// by its parent like this:
//
// const ParentForm = () => {
//   const [value, setValue] = useState(0)
//   return (
//     <NumberSelector
//       min={-10}
//       max={10}
//       value={value}
//       onChange={setValue}
//       css={{ background: theme.white }}
//     />
//   )
// }

const NumberSelector = ({
  min = -10,
  max = 10,
  value,
  onChange: setValue,
  className,
}) => {
  const [tempValue, tempSetValue] = useState(0)
  useEffect(() => {

  }, [tempValue])
  return (
    <div
      css={{
        display: "flex",
        border: `3px solid ${theme.richBlack}`,
        borderRadius: 5,
      }}
      className={className}
    >
      <StepButton
        aria-label="Reduce by one"
        tabIndex="-1"
        onClick={() => {
          setValue((prev) => prev - 1)
        }}
      >
        <svg width="16" height="16" viewBox="0 0 16 16">
          <rect x="0" y="6.5" width="16" height="3" fill={theme.richBlack} />
        </svg>
      </StepButton>
      
      <input
        type="text"
        maxLength={Math.max(min.toString().length, max.toString().length + 1)}
        css={inputStyles}
        value={tempValue}
        onChange={(e) => tempSetValue(e.target.value)}
      />

      <StepButton
        aria-label="Increase by one"
        tabIndex="-1"
        onClick={() => {
          setValue((prev) => prev + 1)
        }}
      >
        <svg width="16" height="16" viewBox="0 0 16 16">
          <rect x="0" y="6.5" width="16" height="3" fill={theme.richBlack} />
          <rect x="6.5" y="0" width="3" height="16" fill={theme.richBlack} />
        </svg>
      </StepButton>
    </div>
  )
}

export default NumberSelector

NumberSelector.propTypes = {
  min: PropTypes.number,
  max: PropTypes.number,
  value: PropTypes.number.isRequired,
  onChange: PropTypes.func.isRequired,
  className: PropTypes.string,
}
42fyovps

42fyovps1#

由于NumberSelector组件完全由父组件控制,因此不应该使用本地状态来存储值。useEffect也是不必要的。
然后可以附加一个onBlur处理程序来限制该值。

<input
    type="text"
    maxLength={Math.max(min.toString().length, max.toString().length + 1)}
    value={value}
    onChange={e => setValue(e.target.value)}
    onBlur={e => {
      if (value && !isNaN(value))
        setValue(Math.min(max, Math.max(min, value)));
    }}
/>

对于递增和递减按钮,您需要检查递增后值不会超出有效范围。

<StepButton
    aria-label="Reduce by one"
    tabIndex="-1"
    onClick={() => setValue(Math.max(min, value - 1))}>
// ...
<StepButton
    aria-label="Increase by one"
    tabIndex="-1"
    onClick={() => setValue(Math.min(max, value + 1))}>
hxzsmxv2

hxzsmxv22#

这与React无关。
据我所知,你正在寻找的数值。然后:

<input
    type="number"
    min={min}
    max={max}
    css={inputStyles}
    value={tempValue}
    onChange={(e) => tempSetValue(e.target.value)}
  />

更多信息Input type

hxzsmxv2

hxzsmxv23#

通常不建议使用useEffect进行任何侧修改。
您可以尝试在onChange中进行一些自定义处理

const onTempChange = (e) => {
    // default to 1 if no input is entered
    let tempFloat = parseFloat(e.target.value || '1');
    // default to 1 if input is invalid
    if (isNan(tempFloat) {
        tempFloat = 1;
    } else {
        tempFloat = Math.min(max, Math.max(min, tempFloat));
    }
    // usually you name the setter something like setTempValue
    tempSetValue(tempFloat);
};

return (
    // ...
    <input ... onChange={onTempChange} />
);

显然,代码还有改进的空间,但这是控制给定给setter的输入值的一种方法的要点。
如果您希望这只在用户离开输入后发生,那么您只需要侦听另一个事件(onFocusOut iirc?).
希望这对你有帮助。

相关问题