Cara terbaik untuk mengendalikan pengesahan input nombor dalam React

WBOY
Lepaskan: 2024-09-07 06:40:02
asal
1184 orang telah melayarinya

Berurusan dengan input nombor dalam React boleh menjadi sukar, terutamanya apabila anda perlu memastikan ia mempunyai saiz yang betul atau mempunyai bilangan titik perpuluhan yang betul. Perkara mudah mungkin kelihatan mudah, tetapi sebaik sahaja anda memahami perkara ini dan cuba mencapai pengalaman pengguna tersuai, kod itu boleh menjadi kucar-kacir dengan cepat.

Pendekatan biasa yang kebanyakan kita gunakan ialah menulis logik pengesahan tersuai yang menyekat input pengguna dalam pengendali onChange.

Sesuatu seperti ini

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}
    />
  );
}
Salin selepas log masuk

Logik ini kelihatan baik pada pandangan pertama tetapi jika anda telah mencubanya, anda tahu ia datang dengan banyak tingkah laku yang tidak dijangka dan pelik dan sama sekali bukan pengalaman pengguna yang baik!

Pendekatan lain ialah menggunakan HTML standard elemen dengan pengesahan terbina menggunakan atribut seperti min, maks, maxLength dsb. Walau bagaimanapun, ia tidak mempunyai maklum balas segera dan sekatan input yang biasanya kami ingin laksanakan.

Kami akhirnya Googling ke arah Stack Overflow dan mencari beberapa... penyelesaian hackish.

  • Menggunakan onKeyPress dan sahkan nilai input secara manual.
  • Menggunakan atribut corak dan tambah Regex untuk mengesahkan nombor (yang tidak berfungsi dengan type="number" jadi kita perlu menjadikannya type="text" ).
  • dan apa yang tidak ...

Best way to handle number input validation in React

Selepas banyak percubaan dan kesilapan, akhirnya saya dapati cara yang lebih baik untuk melakukan ini.

Penyelesaian

Kami boleh menggunakan pengesahan input HTML terbina dengan beberapa javascript tersuai untuk membina penyelesaian yang sempurna.

Berikut ialah komponennya

// 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}
    />
  );
}

Salin selepas log masuk

Dengan pendekatan ini, kami boleh menggunakan pengesahan HTML terbina dan juga menyekat input pengguna yang tidak sah untuk nombor.

Best way to handle number input validation in React

Lihat contoh langsung dan main-main

Bonus

Kita boleh menjadikan logik ini lebih boleh digunakan semula dengan mengeluarkannya dalam cangkuk tersuai seperti ini

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,
  };
};
Salin selepas log masuk

Dan gunakannya dalam mana-mana komponen jika diperlukan ( Jelas sekali yang mempunyai elemen input ).

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>
  );
}
Salin selepas log masuk

Jangan ragu untuk menambah ulasan dan mencadangkan penambahbaikan!

Atas ialah kandungan terperinci Cara terbaik untuk mengendalikan pengesahan input nombor dalam React. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan