javascript - Cum pot valida un câmp de tip array în React Hook Form folosind hook-ul useFieldArray?
Am câteva întrebări legate de React Hook Form și modul în care validează câmpurile de tip array.
Încercam să înregistrez câmpul array cu useEffect când componenta se montează, dar apoi am observat că există un hook useFieldArray care nu montează nimic până când nu adaugi un câmp.
Deci, am asta:
const { fields, append, remove } = useFieldArray<FieldValues>({
name: `logic.${index}.questions` as 'logic.0.questions',
})
Și pot vedea acel câmp până când elementul select declanșează evenimentul onChange.
<Select onChange={e => append({ id: e.target.value }) }>...</Select>
Și în funcție de ceea ce adaug, valoarea fields din useFieldArray începe să crească în lungime, astfel încât pot să redau lucruri noi bazate pe asta, cum ar fi:
<Box>
{ fields.map((field) => <Text key={field.id}>{ field.id }</Text> )}
</Box>
Deci, de exemplu aici https://codesandbox.io/s/react-hook-form-usefieldarray-nested-arrays-x7btr?file=/src/index.js
Cum ați valida la trimitere că array-ul are o lungime pozitivă (> 0) și să afișați un mesaj de eroare.
Am observat că poți face asta cu ușurință atunci când câmpurile sunt doar obiecte, dar ce pot să fac pentru a valida, de exemplu, dacă codul pe care l-am postat aici folosind useFieldArray, dacă lungimea fields este mai mare de 0, atunci să trimit formularul, altfel să afișez o eroare (?)
Răspuns #1
Există o funcționalitate nouă recentă în react-hook-form v7.34.0 care oferă acest tip de validare direct din cutie...
Îl configurezi când definești matricea de câmpuri
În cazul tău, vrei regula required: true
useFieldArray({
name: 'test',
rules: {
required: true,
}
})
Și apoi verifici/utilizezi eroarea ca atare
errors?.test?.root?.message
Rețineți, există o altă variantă care vă permite să furnizați un mesaj de eroare personalizat dacă verificarea obligatorie eșuează...
de ex.
rules: {
required: {
value: true,
message: "At least one is required",
}
}
Vezi aici pentru mai multe detalii...
https://react-hook-form.com/api/usefieldarray/
https://github.com/react-hook-form/react-hook-form/issues/6879
https://github.com/react-hook-form/react-hook-form/pull/8562
Răspunsul #2
S-ar putea să nu fie exact ceea ce cauți, dar iată cum am rezolvat problema. Am o configurație similară cu cea din codesandbox-ul pe care l-ai împărtășit, doar că fără câmpuri imbricate și incluzând un buton Remove care va elimina ultimul element fieldArray când este apăsat:
<button onClick={() => controlledFields.length > 1 ? remove(controlledFields.length - 1) : null}>
Remove
</button>
Acest lucru este destul de important, deoarece folosesc validarea required:true în cadrul fieldArray.map(), forțând utilizatorul să elimine câmpurile de input goale și să completeze cel puțin primul. În exemplul pe care l-ați furnizat, acest lucru ar fi
<Box>
{
fields.map((field) => (
<>
<Text
key={field.id}
{...register(`fields.${index}`, {required:true})}
>
{ field.id }
</Text>
{ errors.fields?.[index] &&
<p> { index === 0 ? "Must select at least one" : "Remove empty fields if unused" } </p>
}
</>
))
}
</Box>
