Tengo un formulario de preguntas con entradas personalizadas.
const Input = (props) => { return ( <div> <label className={classes.label}>{props.label} <input className={classes.input} {...props}/> </label> </div> ); }; Obtengo una lista de preguntas del servidor y las configuro en questions . Luego creo un formulario para responder a estas preguntas.
<form onSubmit = {onAnswersSubmit}> {questions?.map((item) => <Input key={item.id} id={item.id} label={item.question}/>)} <Button> Submit </Button> </form>Me gustaría enviar las respuestas de las entradas a la matriz al hacer clic en el botón Enviar, pero no tengo idea de cómo hacerlo.
Puede usar el accesorio onChange de la input html y pasar una función onChange desde su formulario principal para manejar eso de esta manera:
// This is assuming this is inside a functional component const [answers, setAnswers] = useState([]); const onAnswerChange = useCallback((index, answer) => { setAnswers((oldAnswers) => { oldAnswers[index] = answer; return oldAnswers; }); }, [setAnswers]); return <form onSubmit = {onAnswersSubmit}> {questions?.map((item, index) => <Input key={item.id} id={item.id} label={item.question} value={answers[index] ?? ''} onChange={(e) => onAnswerChange(index, evt.target.value)}/>)} <Button> Submit </Button> </form> Luego puede usar el estado almacenado en las answers como parte de su devolución de llamada onAnswersSubmit.
Probablemente deberías usar state para esto. Un estado para la matriz (lo he llamado state ) y otro para capturar las respuestas a las preguntas (un objeto).
Cuando se dispara el oyente onChange de una entrada, llama a handleChange . Esta función toma el nombre y el valor de la entrada (nota: este ejemplo asume que puede agregar una propiedad de name a los datos que recibe de su servidor) y luego actualiza el estado de las answers .
Cuando se hace clic en el botón, el estado de las answers completas (un objeto) se agrega a la matriz de estado principal.
const { useEffect, useState } = React; function Example({ data }) { // Initialise the states const [ state, setState ] = useState([]); const [ answers, setAnswers ] = useState({}); // Push the completed answers object into // the state array, then reset the answers state function handleClick() { setState([ ...state, answers ]); setAnswers({}); } // Get the name and value from the input // and update the answers state function handleChange(e) { const { name, value } = e.target; setAnswers({ ...answers, [name]: value }); } // Log the main state when it changes useEffect(() => console.log(state), [state]); return ( <div> {data.map(obj => { const { id, name, question } = obj; return ( <input key={id} name={name} placeholder={question} onChange={handleChange} /> ); })} <button onClick={handleClick}>Submit</button> </div> ); } const data = [ { id: 1, name: 'name', question: 'What is your name?' }, { id: 2, name: 'age', question: 'How old are you?' }, { id: 3, name: 'location', question: 'Where do you live?' } ]; ReactDOM.render( <Example data={data} />, document.getElementById('react') ); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script> <div id="react"></div>const [answers, setAnswers] = useState([]); const handleAnswerChange = (index, answer) => { let olddata=answers; olddata[index]=answer; setAnswers([...olddata]); } const Input = (props) => { return ( <div> <label className={classes.label}>{props.label} <input className={classes.input} {...props}/> </label> </div> ); }; <form onSubmit = {onAnswersSubmit}> {questions?.map((item) => <Input key={item.id} id={item.id} label={item.question} onChange={handleAnswerChange}/>)} <Button> Submit </Button> </form>