I am using QuillForms to create a form page that has the attribute "formObj" that takes in a list of JSON objects to render the form properly.
I want to pass a list of JSON objects through a component. Essentially, I would create a list of JSON objects that would be passed to a component inside of my return() jsx.
I used a function called getQuestions() in my Home.jsx that does the following:
const getQuestions = () => {
const questions = [...Array(parseInt(numQuestions)).keys()]
let questionPairs = []
questions.forEach((item, index) => {
questionPairs.push({
name: "short-text",
id: String.valueOf(item),
attributes: {
classnames: "example",
nextBtnLabel: "Next",
required: true,
label: "What would you like to suggest?"
}
})
})
return questionPairs;
}
where numQuestions is any integer. However, the I tried implementing a setState variable inside of the function, similar to this post.
I also tried using the useEffect hook for React to try to get the questions as the page loaded. Every time I try to use the useState() inside of my function body, it keeps giving me an error saying too many rerenders.
<Form
formId="2"
formObj={{
blocks: getQuestions(),
settings: {
animationDirection: "vertical",
disableWheelSwiping: false,
disableNavigationArrows: false,
disableProgressBar: false
},
theme: {
font: "Roboto",
buttonsBgColor: "#9b51e0",
logo: {
src: ""
},
questionsColor: "#000",
answersColor: "#0aa7c2",
buttonsFontColor: "#fff",
buttonsBorderRadius: 25,
errorsFontColor: "#fff",
errorsBgColor: "#f00",
progressBarFillColor: "#000",
progressBarBgColor: "#ccc"
}
}}
/>
I want to pass the array that is returned from the getQuestions() function into the attribute blocks, but the form does not render. I suspect there is a problem with the function not passing the values correctly because when I tried to debug it using console.log() and printing out the function value inside the function body, the complete list was returned.
Just a note for people familiar with QuillForms: How can I add more questions dynamically to the block attribute without having to call a function every render?
Any help would be appreciated! Thanks!
>Solution :
seems like you are running into the issue of triggering too many re-renders when using useState() inside the getQuestions() function. One solution to this problem is to move the useState() call outside of the function and pass the state as a prop to the component that contains the Form component. Then, you can use useEffect() to update the state when the numQuestions variable changes.
Here is an example of how you can modify your code to achieve this:
import { useState, useEffect } from "react";
function Home() {
const [questions, setQuestions] = useState([]);
useEffect(() => {
const questionPairs = [];
for (let i = 0; i < numQuestions; i++) {
questionPairs.push({
name: "short-text",
id: String(i),
attributes: {
classnames: "example",
nextBtnLabel: "Next",
required: true,
label: "What would you like to suggest?"
}
});
}
setQuestions(questionPairs);
}, [numQuestions]);
return (
<Form
formId="2"
formObj={{
blocks: questions,
settings: {
animationDirection: "vertical",
disableWheelSwiping: false,
disableNavigationArrows: false,
disableProgressBar: false
},
theme: {
font: "Roboto",
buttonsBgColor: "#9b51e0",
logo: {
src: ""
},
questionsColor: "#000",
answersColor: "#0aa7c2",
buttonsFontColor: "#fff",
buttonsBorderRadius: 25,
errorsFontColor: "#fff",
errorsBgColor: "#f00",
progressBarFillColor: "#000",
progressBarBgColor: "#ccc"
}
}}
/>
);
}
In this modified code, we first declare a state variable questions and initialize it to an empty array using useState(). Then, we use useEffect() to generate the question pairs and update the state whenever numQuestions changes. Finally, we pass the questions state variable to the Form component as a prop.
To add more questions dynamically, you can create a separate function that adds a new question pair to the questions state variable and call it on an event trigger such as a button click. This will trigger a re-render and update the Form component with the new question.