Lo que estoy tratando de hacer aquí es construir un componente dinámico, que será responsable de tomar una serie de objetos y el formulario se construirá en función de mi formState. Así que hice mi estado inicial y usé .map para hacer el bucle sobre el estado y asigné las claves para hacer que la etiqueta, el valor y las entradas aparecieran según el estado. pero mi problema está en onChange. Cómo actualizar la clave de valor en cada objeto y establecer el nuevo estado para él. algún consejo, por favor.
import { useState } from "react"; import InputText from "./components"; import useForm from "./hooks/useForm"; function App() { interface formStateT { id: number; label: string; value: any; error: string; } const formState = [ { id: 0, label: "firstName", value: "", error: "", }, { id: 1, label: "lastName", value: "", error: "", }, ]; const { form, validate, setForm, checkValidHandler } = useForm(formState); const [error, setError] = useState(""); const submitFormHandler = (e: { preventDefault: () => void }) => { e.preventDefault(); checkValidHandler(); // write form logic // setError() will be used to take the error message console.log(form); }; return ( <form onSubmit={(e) => submitFormHandler(e)}> {form.map((f: formStateT) => ( <InputText key={f.id} label={f.label} value={f.value} onChange={(e) => { // Im trying here to update the value key of every label key. // setForm({ ...form, [f.label.valueOf()]: f.value }) }} valid={f.value === "" ? validate.notValid : validate.valid} errorMsg={error === "" ? f.error : error} classes={"class"} /> ))} <button>Submit</button> </form> ); } export default App;De su comentario, f.value = e.target.value; es una mutación de estado y debe evitarse, setForm([...form]); está enmascarando la mutación.
En la App , cree una función onChangeHandler que tome el objeto de evento onChange y el índice que desea actualizar. Descomprima el value del evento onChange y actualice el estado. El controlador debe usar una actualización de estado funcional para actualizar desde el estado anterior y crear una copia superficial de la matriz de form , usando el índice para copiar superficialmente y actualizar el elemento correcto de la matriz.
Ejemplo:
// curried function to close over index in scope, and // return handler function to consume event object const onChangeHandler = index => e => { const { value } = e.target; setForm(form => form.map((el, i) => i === index ? { ...el, value } : el )); }; ... <form onSubmit={submitFormHandler}> {form.map((f: formStateT, index: number) => ( <InputText key={f.id} label={f.label} value={f.value} onChange={onChangeHandler(index)} // <-- invoke and pass mapped index valid={f.value === "" ? validate.notValid : validate.valid} errorMsg={error === "" ? f.error : error} classes={"class"} /> ))} <button>Submit</button> </form>