Estoy tratando de crear un formulario web básico de varias etapas en Javascript. Quería lograr algo así como la sección de formularios de Full Stack Open , creando una colección (una matriz) de preguntas y luego mostrándolas como etiquetas en mi página web, filtradas para que solo aparecieran las apropiadas en ciertos momentos. Por ejemplo, cuando visita la página por primera vez, diría "Las próximas preguntas evaluarán su situación presupuestaria", luego, después de presionar iniciar, pasaría a la primera pregunta, luego presionaría siguiente, a la segunda, y así sucesivamente.
Pensé que logré esto de la manera correcta, al mostrar la colección filtrada (la fase se inicializa en 0 fuera de la aplicación):
const questionPhase = () => { if (phase < 3){ phase = phase + 1; } else if(phase == 3){ phase = 0; addToBudget(attribute); } console.log(phase); } return ( <div> <h3> Please answer some questions to start</h3> <ul> {questions.filter(question => question.phase === phase).map(question => { < label > {question.script} <input type="text" question = {question.attribute} value={question.attribute} onChange={handleInput} /> </label>})} </ul> <button onClick={questionPhase}> {phase === 2 ? 'Next' : 'Submit'} </button> </div> )Realicé algunos registros y determiné que la fase en realidad está cambiando cada vez que presiono el botón en la parte inferior. Pero lo que no sucede es que se muestren las preguntas (y las etiquetas) o que cambien las letras de los botones.
No estoy seguro de lo que he hecho mal? Estoy seguro de que hay algún aspecto sutil del flujo de control que me he perdido, pero no sé qué: pensé que, como se explica en FSO, la aplicación se ejecuta continuamente cada vez que hay un cambio presionando un botón o algo, que debería ser el evento creado por la pulsación del botón.
Gracias de antemano por cualquier ayuda
apéndice: aquí está la clase questionList (desde la cual se importan las preguntas) y el controlador de eventos:
import React from 'react' const questions = [ { phase: 1 , script: 'What is your monthly income?', attribute: "income" }, { phase: 2, script: 'what are you monthly expenses?', attribute: "expenses" } ] export default questions const handleInput = (event) => { const value = event.target.value; console.log('valued!') setAttribute({ ...attribute, [event.target.question]: value }) }Lo único que activará una nueva representación en React es un cambio de estado, por lo que si el cambio de una variable debe causar una nueva representación, debe mantenerlo en el estado.
Puede cambiar su componente questionPhase a una clase o función (lo mismo), y luego en el constructor, definir
este.estado = {fase};
Entonces this.state.phase será igual a cualquier fase que haya cuando se creó la instancia del componente. Querrá cambiar el resto del componente para usar esa variable. La forma correcta de cambiar su valor y activar una nueva representación es con una llamada a setState.
Esa es la forma en que yo lo haría; aunque sería más fácil simplemente llamar a forceUpdate. Eso hará que la reacción se vuelva a renderizar. Sin embargo, no es la forma de reaccionar. El propósito completo de reaccionar es vincular fuertemente la interfaz de usuario al estado subyacente, por lo que no recomendaría usar forceUpdate.