Tengo un formulario de varios pasos, que estoy haciendo usando reaccionar, para trabajar en la validación estoy usando react-hook-form .
Ya he logrado el 90% de las cosas, solo una de las cosas a las que me enfrento es obtener los datos del segundo formulario, que son dinámicos.
lo que estoy haciendo es
asunto
Que he hecho
En mi componente principal, estoy haciendo esto para la validación.
const forms = [ { fields: ['desig', 'dept'], component: () => ( <Pro register={register} errors={errors} defaultValues={defaultValues} /> ), }, { fields: [ `userInfo[0].fname`, // here I am facing issue if I am statically putting 0,1 then it is validating that perticular form `userInfo[0].sirname`, ], component: () => ( <Basic register={register} errors={errors} defaultValues={defaultValues} inputHolder={inputHolder} deleteRow={deleteRow} addRow={addRow} /> ), }, ];Al hacer clic en enviar, estoy haciendo esto
const handleSubmit = (e) => { triggerValidation(forms[currentForm].fields).then((valid) => { if (valid) { console.log('whole form data - ', JSON.stringify(defaultValues)); } }); };y aquí quiero datos como a continuación si se agregan dos datos en form2
{ "fname": "dsteve", "sname": "smith", "userInfo": [ { "desig": "ddd", "dept": "deptee" }, { "desig": "ddd", "dept": "deptee" } ] }he hecho de todo pero aqui solo me he quedado atascado, se donde esta el tema
En lugar de esto
fields: ["fname", "sname"],tengo que hacer asi
fields:[`userInfo[0].name, `userInfo[0].sname],Este 0-1 lo tengo que hacer dinamico segun indices, no se que me falta
Traté de mapear los campos con índice a través de inputHolder pero no funcionó
Editar / Actualizar
Si estoy haciendo esto
fields:[`userInfo[0].name`,`userInfo[1].name`, `userInfo[0].sname`,`userInfo[1].sname],Por lo tanto, está tomando la validación de dos campos, pero eso es manual, lo estoy dominando, si el usuario crea más campos, entonces eso debería tomar estos campos dinámicamente.
Aquí está mi sandbox de código, que contiene el código completo
Aquí está mi caja de arena de código
Estoy abierto a usar cualquier enfoque nuevo, pero eso debería usar react-hook-form y completar lo que estoy tratando de hacer.
No sé cómo progresar con mi enfoque ahora
Te recomiendo que uses yup como utilidad de validación. Es una herramienta poderosa.
import * as yup rom 'yup'; const schema = yup.object().shape({ field1: yup.string().required() // number, array - whatever, field2: yup.string().required(), })También se debe crear un esquema similar para la segunda forma
import { yupResolver } from '@hookform/resolvers/yup'; const { register, handleSubmit } = useForm({ resolver: yupResolver(schema), });Haga lo mismo para su segundo formulario: useForm + validación de resolución .
la siguiente parte es hacer que su segundo formulario sea dinámico, así que use el gancho useFieldArray
const { fields, append, remove } = useFieldArray({ name: 'userInfo', *// key, a part of path to access your fields - userInfo[n].fname* control: form.control, *// to connect you fields to basic form* });Ahora puede crear acciones*(botones/enlaces)* y pasarles {agregar, eliminar} acciones.
{fields} debe ser representado por .map por defecto. una vez que intente validar su segundo formulario con (n) sección de descuento, su esquema se aplicará a cada una de las secciones.
hay otra solución, puede omitir parte con la segunda forma (preferiría de esta manera si su segundo esquema pudiera ser masivo).
puede conectar sus campos useFieldArray a la primera forma, y su esquema de validación único se ve así:
import * as yup rom 'yup'; const infoSchema = yup.object().schema({ firstName: yup.string(), lastName: yup.string(), }) *// enhance infoSchema to your expected logic.* const schema = yup.object().shape({ field1: yup.string().required() // number, array - whatever, field2: yup.string().required(), userInfo: yup.array().of(infoSchema), })Puede crear una matriz de 2 cadenas vacías donde la primera representa el nombre F de la primera fila, y la segunda representa el nombre S de la primera fila bajo su inputHolder en el componente principal:
const [inputHolder, setinputHolder] = useState([ { id: 1, fname: "", sname: "" } ]); const [names, setNames] = useState(["", ""]);Luego, cada vez que el usuario anuncia una nueva fila, agrega cadenas vacías en la matriz de nombres.
const addRow = () => { console.log(inputHolder.length); let item = { id: inputHolder.length + 1, fname: "", sname: "" }; setinputHolder([...inputHolder, item]); setNames([...names, "", ""]); };Donde cada cadena vacía representa el nombre F y el nombre S. Finalmente, los campos se establecen en nombres en segunda forma:
fields: names, component: (register, errors, defaultValues) => ( <Form2 register={register} errors={errors} defaultValues={defaultValues} inputHolder={inputHolder} addRow={addRow} />