Jak vytvářet formuláře v Reactu

10.03.2024 Programování #react #forms #formulare

Formuláře hrají v moderních webových aplikacích zásadní roli. Umožňují uživatelům sdílet informace, plnit úkoly a poskytovat zpětnou vazbu.


Bez formulářů by nebylo možné mnoho úkolů, které na webu považujeme za samozřejmé, jako je přihlašování, přihlašování nebo nakupování.

Naučit se vytvářet efektivní a uživatelsky přívětivé formuláře je proto nezbytné pro vývojáře, kteří chtějí vytvářet poutavé a interaktivní webové aplikace.

Se svou rozsáhlou sbírkou vestavěných háků poskytuje React několik funkcí a technik pro vytváření a správu formulářů, včetně správy stavu, zpracování událostí a ověřování formulářů.

Účelem této příručky je poskytnout komplexní a hloubkový pohled na vytváření formulářů v Reactu.

Začínáme...

V Reactu existují dva způsoby zpracování dat formuláře:

  • Řízené komponenty: V tomto přístupu jsou data formuláře zpracovávána Reactem pomocí háčků, jako je hák useState.
  • Nekontrolované komponenty: Data formuláře jsou zpracovávána objektovým modelem dokumentu (DOM) spíše než Reactem. DOM udržuje stav dat formuláře a aktualizuje je na základě vstupu uživatele.

Abyste lépe porozuměli rozdílu mezi řízenými a neřízenými komponenty, zvažte, že existují dva způsoby jízdy na kole.

V prvním přístupu necháte kolo převzít kontrolu. Sednete na motorku a necháte ji rozhodnout o směru a rychlosti. Můžete se pokusit, aby to šlo určitým směrem nakloněním těla, ale nakonec se kolo rozhodne, kam jet.

Je to podobné jako u nekontrolovaných komponent v Reactu. Vložíte prvek formuláře do komponenty a DOM nad ním převezme kontrolu. DOM rozhoduje o stavu vstupního prvku a aktualizuje jej na základě vstupu uživatele.

Ve druhém přístupu převezmete kontrolu nad kolem. Držíte řídítka a pedály a rozhodujete se, kam pojedete a jak rychle pojedete. Podle potřeby můžete snadno zpomalit nebo zrychlit.

Je to podobné jako u řízených komponent, kde komponenta React přebírá kontrolu nad daty formuláře a udržuje stav prvků formuláře. Komponenta rozhoduje o tom, kdy a jak aktualizovat stav, a na základě změn stavu se znovu vykreslí.

V nadcházejících částech vysvětlíme rozdíl mezi řízenými a neřízenými součástmi a poskytneme praktické příklady, které ilustrují, jak každá z nich funguje.

Kontrolované komponenty v React

V Reactu je řízená komponenta komponenta, kde prvky formuláře odvozují svou hodnotu ze stavu React.

Když je komponenta řízena, hodnota prvků formuláře je uložena ve stavu a jakékoli změny provedené v hodnotě se okamžitě projeví ve stavu.

Chcete-li vytvořit řízenou komponentu, musíte použít rekvizitu value k nastavení hodnoty prvků formuláře a onChange události pro zpracování změn provedených v hodnotě.

Prop value nastaví počáteční hodnotu prvku formuláře, zatímco onChange událost se spustí, kdykoli se změní hodnota prvku formuláře. Uvnitř onChange události musíte aktualizovat stav novou hodnotou pomocí funkce aktualizace stavu.

Zde je příklad:

import React from "react" 
import ReactDOM from "react-dom"
import { useState } from "react";

export default function  ControlledComponent()  {
	const  [inputValue, setInputValue] =  useState('');

	const  handleChange = (event) => {
		setInputValue(event.target.value);
	};

return  (
<form>
	<label>Input Value:
	<input  type="text"  value={inputValue} onChange={handleChange} />
	</label>
	<p>Input Value: {inputValue}</p>
</form>
)};

ReactDOM.render(<ControlledComponent />, document.getElementById('root'));

V tomto příkladu:

Hák useState definuje stavovou proměnnou (inputValue) a funkci aktualizace stavu (setInputValue).

Prop value nastaví počáteční hodnotu vstupního prvku na hodnotu inputValue.

Událost také onChange zpracovává změny provedené ve vstupní hodnotě. Funkce handleChange aktualizuje inputValue stav novou hodnotou vstupního prvku a aktualizovaná hodnota se okamžitě projeví ve stavu a zobrazí se na obrazovce.

Když uživatel píše do vstupního pole, handleChange funkce aktualizuje stavovou proměnnou pomocí funkce "setInputValue". Komponenta se poté znovu vykreslí a value atribut vstupního pole se aktualizuje tak, aby odrážel novou hodnotu inputValue.

Hodnota vstupního pole a text zobrazený pod ním jsou vždy synchronizované, což z něj činí řízenou komponentu.

Jak zacházet s rozevíracími seznamy a zaškrtávacími políčky v Řízených komponentách

Stejně jako u vstupních prvků lze hodnotu rozevíracího seznamu nastavit pomocí prop value ve spojení s onChange obslužnou rutinou události k aktualizaci stavu komponenty.

Chcete-li například pracovat s rozevírací nabídkou, můžete definovat počáteční hodnotu rozbalovací nabídky ve stavu komponenty a poté aktualizovat stav, když se hodnota rozbalovací nabídky změní:

import React from "react" 
import ReactDOM from "react-dom"
import { useState } from "react";

export default function Dropdown()  {
	const [selectedOption, setSelectedOption] = useState("option1");

	const  handleDropdownChange = (event) => {
		setSelectedOption(event.target.value);
	};

return  (
	<div>
		<label>
			Select an option:
				<select  value={selectedOption} onChange={handleDropdownChange}>
				<option  value="option1">Option 1</option>
				<option  value="option2">Option 2</option>
				<option  value="option3">Option 3</option>
			</select>
		</label>
		<p>Selected option: {selectedOption}</p>
	</div>
	);
}

ReactDOM.render(<Dropdown />, document.getElementById('root'));

Podobně můžete zaškrtávací políčka zpracovat tak, že nastavíte checked podpěru vstupního prvku zaškrtávacího políčka na základě stavu komponenty a poté stav aktualizujete po kliknutí na zaškrtávací políčko.

Zde je příklad:

import React from "react" 
import ReactDOM from "react-dom"
import { useState } from "react";

function Checkbox() {
  const [isChecked, setIsChecked] = useState(false);

  const handleChange = (event) => {
    setIsChecked(event.target.checked);
  };

  return (
    <form>
      <label htmlFor="color">
        <input type="checkbox" name="color" checked={isChecked} onChange={handleChange}/>
        Blue
      </label>

      {isChecked && <div>Blue is selected!</div>}
    </form>
  );
}

export default Checkbox;

ReactDOM.render(<Checkbox />, document.getElementById('root'));

V tomto příkladu jsme definovali stavovou proměnnou, isChecked abychom mohli sledovat, zda je zaškrtávací políčko zaškrtnuto nebo ne. Po kliknutí na zaškrtávací políčko handleChange se zavolá funkce a aktualizuje isChecked stavovou proměnnou na novou hodnotu (pravda nebo nepravda).

Proměnná isChecked řídí checked atribut vstupu zaškrtávacího políčka a podmíněně vykresluje zprávu označující, že je zaškrtávací políčko vybráno.

Jak zacházet s více poli formuláře

Při práci s formuláři v Reactu je běžné mít několik prvků formuláře, jako jsou textové vstupy, zaškrtávací políčka, přepínače a další.

Chcete-li spravovat stav těchto prvků formuláře, můžete definovat hodnoty pro vstupní pole jako objekt pomocí jedné stavové proměnné a aktualizovat každou příslušnou stavovou proměnnou pomocí události onChange.

Předpokládejme například, že chcete vytvořit formulář s následujícími poli:

  • Zadání textu pro jméno uživatele
  • E-mailové pole pro e-mail uživatele
  • Pole textové oblasti pro zprávu uživatele

S těmito poli můžete zacházet takto:

import React from "react" 
import ReactDOM from "react-dom"
import { useState } from "react";

export default function Multiple() {
  const [formData, setFormData] = useState({name: "",email: "",message: ""});

  const handleChange = (event) => {
    const { name, value } = event.target;
    setFormData((prevFormData) => ({ ...prevFormData, [name]: value }));
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    alert(`Name: ${formData.name}, Email: ${formData.email}, Message: ${formData.message}`
    );
};

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="name">Name:</label>
      <input type="text" id="name" name="name" value={formData.name} onChange={handleChange}/>

      <label htmlFor="email">Email:</label>
      <input type="email" id="email" name="email" value={formData.email} onChange={handleChange}/>

      <label htmlFor="message">Message:</label>
      <textarea id="message" name="message" value={formData.message} onChange={handleChange}/>

      <button type="submit">Submit</button>
    </form>
  );
}

ReactDOM.render(<Multiple />, document.getElementById('root'));

 

V ukázkovém kódu:

Hák useState definuje pojmenovaný objekt stavu formData, který obsahuje tři vlastnosti: nameemail message, z nichž každá je inicializována na prázdný řetězec.

Funkce handleChange je volána vždy, když uživatel zadá jedno z polí formuláře. Extrahuje name value z pole formuláře, které se změnilo pomocí event.target objektu, a poté formData pomocí funkce aktualizuje stavovou proměnnou setFormData.

Funkce setFormData používá operátor spread ( ...) ke zkopírování předchozího formData objektu. Potom aktualizuje hodnotu změněného pole formuláře nastavením jeho hodnoty prop na novou hodnotu.

Použitím objektu ke správě dat formuláře můžeme snadno sledovat hodnoty více prvků formuláře. To usnadňuje správu a manipulaci se stavem našich formulářových dat, zejména při práci se složitými formuláři s mnoha formulářovými prvky.

Jak ověřit zadání formuláře

Ověřování formulářů se týká procesu kontroly uživatelských vstupních dat, aby se zajistilo, že splňují specifická kritéria nebo požadavky, než jsou odeslána na server nebo použita jiným způsobem.

Ověření formuláře může mít různé formy v závislosti na typu a složitosti shromažďovaných dat. Mezi běžné typy ověřování formulářů patří:

  • Ověření povinného pole: Kontrola, zda povinná pole nezůstala prázdná.
  • Ověření formátu: Zajištění, že vstupní data jsou ve správném formátu (například e-mailové adresy, telefonní čísla atd.).
  • Ověření délky: Kontrola, zda jsou vstupní data v určitém rozsahu délek.
  • Ověření vzoru: Kontrola, zda vstupní data odpovídají konkrétnímu vzoru.

Mezi běžné metody ověřování formulářů patří použití vestavěných ověřovacích atributů HTML, jako jsou requiredminlength maxlength, a také použití React k provádění vlastní logiky ověření.

Předpokládejme například, že máme formulář se vstupním polem, které vyžaduje minimálně 5 znaků. Stav můžeme použít ke sledování hodnoty vstupního pole a zobrazení chybové zprávy, pokud je délka hodnoty menší než 5.

import React from "react" 
import ReactDOM from "react-dom"
import { useState } from 'react';

function MyForm() {
  const [inputValue, setInputValue] = useState('');
  const [inputError, setInputError] = useState(null);

  function handleInputChange(event) {
    const value = event.target.value;
    setInputValue(value);

    if (value.length < 5) {
      setInputError('Input must be at least 5 characters');
    } else {
      setInputError(null);
    }
  }

  function handleSubmit(event) {
    event.preventDefault();
    if (inputValue.length >= 5) {
      // submit form
    } else {
      setInputError('Input must be at least 5 characters');
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Fruit:
        <input type="text" value={inputValue} onChange={handleInputChange} />
      </label>
      {inputError && <div style={{ color: 'red' }}>{inputError}</div>}
      <button type="submit">Submit</button>
    </form>
  );
} 

ReactDOM.render(<MyForm />, document.getElementById('root'));

 

V tomto příkladu máme jednoduchý formulář, který umožňuje uživateli zadat název ovoce. Formulář má dva stavy:

  • inputValue: Představuje aktuální hodnotu vstupního pole
  • inputError: Představuje jakékoli chyby, které mohou nastat během ověřování formuláře.

Funkce handleInputChange je volána pokaždé, když uživatel zadá znak do vstupního pole. Aktualizuje inputValue stav tak, aby odrážel aktuální hodnotu vstupního pole, a poté zkontroluje, zda je hodnota dlouhá alespoň 5 znaků.

Pokud je hodnota menší než 5 znaků, nastaví stav inputError na příslušnou chybovou zprávu. V opačném případě nastaví inputError stav na null (označuje, že nejsou žádné chyby).

Nekontrolované komponenty v Reactu

Neřízené komponenty v Reactu odkazují na prvky formuláře, jejichž stav není spravován Reactem. Místo toho je jejich stav zpracováván DOM prohlížeče.

Řekněme například, že máte formulář, který se skládá z textového vstupního pole, výběrového pole a zaškrtávacího políčka. V řízené komponentě byste vytvořili stav pro každý prvek formuláře a napsali obslužné rutiny událostí, aby se stav aktualizoval pokaždé, když uživatel interaguje s kterýmkoli z prvků formuláře.

Naproti tomu neřízená komponenta umožňuje prohlížeči zpracovávat stav prvků formuláře. Když uživatel zadá text do textového vstupního pole nebo vybere možnost z výběrového pole, prohlížeč automaticky aktualizuje stav DOM pro tento prvek.

Chcete-li získat hodnotu neřízeného prvku formuláře, můžete použít funkci nazvanou "ref". "Refs" poskytují způsob, jak získat přístup k aktuální hodnotě prvků DOM. Pomocí háčku můžete vytvořit „odkaz“ useRefa poté jej připojit k prvku formuláře, ke kterému chcete získat přístup. To vám umožňuje kdykoli získat aktuální hodnotu prvku, aniž byste museli spravovat jeho stav v komponentě React.

Zde je příklad nekontrolované komponenty:

import React from "react" 
import ReactDOM from "react-dom"
import { useRef } from "react";

export default function Uncontrolled() {
  const selectRef = useRef(null);
  const checkboxRef = useRef(null);
  const inputRef = useRef(null);

  function handleSubmit(event) {
    event.preventDefault();
    console.log("Input value:", inputRef.current.value);
    console.log("Select value:", selectRef.current.value);
    console.log("Checkbox value:", checkboxRef.current.checked);
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        <p>Name:</p>
        <input ref={inputRef} type="text" />
      </label>
      <label>
        <p>Favorite color:</p>
        <select ref={selectRef}>
          <option value="red">Red</option>
          <option value="green">Green</option>
          <option value="blue">Blue</option>
        </select>
      </label>
      <label>
        Do you like React?
        <input type="checkbox" ref={checkboxRef} />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}


ReactDOM.render(<Uncontrolled />, document.getElementById('root'));

V tomto příkladu:

Máme formulář, který obsahuje pole pro zadávání textu, výběrové pole a zaškrtávací políčko. Místo vytváření stavu pro každý prvek formuláře a psaní obslužných rutin událostí k aktualizaci stavu používáme neřízené komponenty. To znamená, že prohlížeč je zodpovědný za správu stavu prvků formuláře.

Když uživatel interaguje s prvkem formuláře, prohlížeč automaticky aktualizuje stav modelu DOM pro tento prvek. A k načtení aktuálních hodnot každého prvku formuláře používáme háček useRef.

Neřízené komponenty mohou být užitečné v určitých situacích, například když se potřebujete integrovat s knihovnami třetích stran nebo když nepotřebujete manipulovat s daty formuláře.

Celkově vzato představují neřízené komponenty jednodušší přístup k práci s formuláři v Reactu a mohou váš kód učinit stručnějším a čitelnějším. Je však důležité poznamenat, že použití ref pro přístup k hodnotám prvků formuláře může ztížit testování a údržbu vašeho kódu, takže je používejte uvážlivě.

Literatura:

https://www.freecodecamp.org/news/tag/react/