Heim  >  Artikel  >  Web-Frontend  >  Der beste Weg, um die Validierung der Zahleneingabe in React zu handhaben

Der beste Weg, um die Validierung der Zahleneingabe in React zu handhaben

WBOY
WBOYOriginal
2024-09-07 06:40:021149Durchsuche

Der Umgang mit Zahleneingaben in React kann mühsam sein, insbesondere wenn Sie sicherstellen müssen, dass sie die richtige Größe haben oder die richtige Anzahl an Dezimalstellen haben. Einfache Dinge mögen einfach erscheinen, aber wenn man sich erst einmal ans Eingemachte macht und versucht, benutzerdefinierte Benutzererlebnisse zu erreichen, kann der Code schnell chaotisch werden.

Ein gängiger Ansatz, den die meisten von uns verwenden, besteht darin, eine benutzerdefinierte Validierungslogik zu schreiben, die die Benutzereingabe im onChange-Handler einschränkt.

So etwas in der Art

function NumberInput({
  value,
  onChange,
  min,
  max,
}: {
  value: number;
  onChange: (val: number) => void;
  min?: number;
  max?: number;
}) {
  const changeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
    const val = +e.target.value;
    if (min != null && val < min) {
      onChange(min);
      return;
    }
    if (max != null && val > max) {
      onChange(max);
      return;
    }
    onChange(val);
  };

  return (
    <input
      type="number"
      value={value}
      onChange={changeHandler}
    />
  );
}

Diese Logik sieht auf den ersten Blick gut aus, aber wenn Sie sie bereits ausprobiert haben, wissen Sie, dass sie viele unerwartete und seltsame Verhaltensweisen mit sich bringt und überhaupt keine gute Benutzererfahrung bietet!

Ein anderer Ansatz ist die Verwendung von Standard-HTML Element mit den eingebauten Validierungen unter Verwendung von Attributen wie min, max, maxLength usw. Es fehlen jedoch das sofortige Feedback und die Eingabebeschränkungen, die wir normalerweise implementieren möchten.

Am Ende googeln wir uns nach Stack Overflow und finden einige... hackige Lösungen.

  • Verwenden Sie onKeyPress und validieren Sie die Eingabewerte manuell.
  • Verwenden Sie das Musterattribut und fügen Sie Regex hinzu, um die Zahl zu validieren (was mit type="number" nicht funktioniert, also müssen wir es zum Typ="text" machen).
  • und was nicht...

Best way to handle number input validation in React

Nach vielen Versuchen und Irrtümern habe ich endlich einen besseren Weg gefunden, dies zu tun.

Die Lösung

Wir können die integrierte HTML-Eingabevalidierung mit benutzerdefiniertem Javascript nutzen, um eine perfekte Lösung zu erstellen.

Hier ist die Komponente

// Interface for props overriding the default value and onChange
// attribute to accept only numeric value
export interface NumberInputProps
  extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange"> {
  onChange: (val: number) => void;
  value: number;
}

function NumberInput({
  value,
  onChange,
  min,
  max,
  step,
  ...props
}: NumberInputProps) {
  // Internal input state to avoid weird behaviors with empty inputs
  const [input, setInput] = React.useState(value?.toString() || "");

  const changeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
    // Using HTML input validity API to validation
    if (
      (max != null && e.target.validity.rangeOverflow) ||
      (min != null && e.target.validity.rangeUnderflow) ||
      (step != null && e.target.validity.stepMismatch)
    )
      return;

    const val = +e.target.value;
    setInput(e.target.value);
    onChange(val);
  };

  // To ensure the external updates are reflected in the input element
  React.useEffect(() => {
    setInput(value.toString());
  }, [value]);

  return (
    <Input
      ref={ref}
      type="number"
      value={input}
      onChange={changeHandler}
      min={min}
      max={max}
      step={step}
      {...props}
    />
  );
}

Mit diesem Ansatz können wir die integrierten HTML-Validierungen nutzen und auch die ungültige Benutzereingabe für Zahlen einschränken.

Best way to handle number input validation in React

Sehen Sie sich Live-Beispiele an und spielen Sie herum

Bonus

Wir können diese Logik wiederverwendbar machen, indem wir sie in einem benutzerdefinierten Hook wie diesem extrahieren

export const useNumberInput = ({
  value,
  onChange,
  min,
  max,
  step,
}: {
  value: number;
  onChange: (val: number) => void;
  max?: number;
  min?: number;
  step?: number;
}): InputHTMLAttributes<HTMLInputElement> => {
  const [input, setInput] = useState(value?.toString() || "");

  const changeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (
      (max != null && e.target.validity.rangeOverflow) ||
      (min != null && e.target.validity.rangeUnderflow) ||
      (step != null && e.target.validity.stepMismatch)
    )
      return;

    const val = +e.target.value;
    setInput(e.target.value);
    onChange(val);
  };

  useEffect(() => {
    setInput(value.toString());
  }, [value]);

  return {
    type: "number",
    value: input,
    onChange: changeHandler,
    min,
    max,
    step,
  };
};

Und verwenden Sie es bei Bedarf in jeder Komponente (die natürlich über ein Eingabeelement verfügt).

export default function CustomInput() {
  const [value, setValue] = useState(0);
  const inputProps = useNumberInput({
    value,
    onChange: setValue,
    min: 1,
    max: 50,
  });

  return (
    <div>
      <button onClick={() => onChange(value + 1)}>
        +
      </button>
      <button onClick={() => onChange(value - 1)}>
        -
      </button>
      <input
        {...inputProps}
        {...otherProps}
      />
    </div>
  );
}

Fügen Sie gerne Kommentare hinzu und schlagen Sie Verbesserungen vor!

Das obige ist der detaillierte Inhalt vonDer beste Weg, um die Validierung der Zahleneingabe in React zu handhaben. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn