Creé dos componentes que juntos crean un formulario de entrada de estilo 'progresivo'. La razón por la que elegí este método es porque las preguntas pueden cambiar el texto o cambiar el orden y, por lo tanto, se incorporan al componente desde una matriz almacenada en un archivo JS llamado CustomerFeedback.
Hasta ahora, he estado tratando de agregar una función de controlador de datos que se activará cuando el usuario haga clic en el botón 'Continuar'. La función debe recopilar todas las respuestas de todas las preguntas presentadas y almacenarlas en una matriz llamada RawInputData. Me las arreglé para hacer que esto funcione en una versión codificada de SurveyForm usando el código que se muestra a continuación, pero no encontré una manera de hacerlo lo suficientemente dinámico para usarlo junto con un componente de SurveyQuestion. ¿Alguien puede ayudarme a hacer que la función dataHander recopile datos dinámicamente?
Ahí lo que he hecho:
https://codesandbox.io/s/angry-dew-37szi2?file=/src/InputForm.js:262-271
Entonces, podemos hacerlo más fácil, solo puede pasar los datos necesarios cuando llame al controlador de accesorios:
const inputRef = React.useRef(); const handleNext = () => { props.clickHandler(props.reference, inputRef.current.value); };Y fusionarlo en el componente InputForm:
const [inputData, setInputData] = useState({}); const handler = (thisIndex) => (key, value) => { if (thisIndex === currentIndex) { setCurrentIndex(currentIndex + 1); setInputData((prev) => ({ ...prev, [key]: value })); } }; // ... <Question // ... clickHandler={handler(question.index)} />Entonces, quería una matriz (objeto más coniniente, creo), puede guardar datos como una matriz si lo desea:
setInputData(prev => [...prev, value])Inicialmente, pensé que desea recopilar datos sobre los clics de botón en InputForm, pero aparentemente puede prescindir de esto, esta solución es más simple
UPD Apouach que usa useImperativeHandle: si queremos activar alguna lógica de nuestros componentes secundarios, debemos crear un identificador para esto con la ayuda de forwarfRef+useImperativeHandle:
const Question = React.forwardRef((props, ref) => { const inputRef = React.useRef(); React.useImperativeHandle( ref, { getData: () => ({ key: props.reference, value: inputRef.current.value }) }, [] );Después de esto, podemos guardar todas nuestras referencias en el componente principal:
const questionRefs = React.useRef( Array.from({ length: QuestionsText.length }) ); // ... <Question key={question.id} ref={(ref) => (questionRefs.current[i] = ref)}Y podemos tratar estos datos cuando queramos:
const handleComplete = () => { setInputData( questionRefs.current.reduce((acc, ref) => { const { key, value } = ref.getData(); return { ...acc, [key]: value }; }, {}) ); };Vea cómo se usa ref aquí: https://reactjs.org/docs/forwarding-refs.html https://reactjs.org/docs/hooks-reference.html#useimperativehandle
Todavía recomiendo encarecidamente usar la forma de gancho de reacción con formularios anidados para manejarlo