I am working with the next js to handle a question form, I have multiple questions that have multiple answers, and the user may select one or multiple tags for a question.
if a user selects one or more tag
to answer a question it must increment
the counter
just one time, If a user unselect a tag
it must not decrement
until unselect the last tag of the related question.
1 – When the user selects a tag of a question at first increment the counter, but it must not increment when I select the second tag in the same question.
2 – When the user unselects tags of question it must not decrement if any one of them is selected it must not decrement until the last one is unselected.
Now when selecting the first tag it increments the counter but after that, if I select or unselect, it does not decrement or increment.
Please help me to handle this.
My code:
<TageQuestion key={item.attributes.Number} id={item.attributes.Number} data={item} name={`${item.attributes.Number}`} errors={errors} touched={touched} handleSelectOption={handleSelectOption} />
The component:
<div className="mt-3"> {Object.keys(attributes.options).map(item => ( <div className="inline" key={item}> <input {...feild} {...props} className="hidden" id={item} value={item} type="checkbox" name={`${name}[answer]`} /> <label htmlFor={item} id={item + "lable"} onClick={e => { selectTage(e.target); handleSelectOption(`question${id}`, item); }} className="inline-flex items-center px-3 py-0.5 rounded-full text-sm font-medium bg-gray-100 text-gray-800 mr-3 mb-2 cursor-pointer" > {item} </label> </div> ))} </div>
The function:
function handleSelectOption(title, item) { setCompareTagTitle(title); if (title !== compareTagTitle) { setTagItem([...tagItem, item]); setCounter(++counter); } else if (title === compareTagTitle) { setCounter(counter); } else { setCounter(--counter); } }
Data that come from the backend:
Advertisement
Answer
we should consider 2 steps first in child component TagQuestions
then in parent component [type].js
step1:
//TagQuestions.js const [intialRender, setIntialRender] = useState(true); // if component render for first time const selectTag = (e) => { // we should change intialRender to false to say that user select somthing .... if (tage.length > 0) { const isExit = tage.filter((item) => item.name === el.innerHTML); if (isExit.length === 0) { setTage([...tage, { name: el.innerHTML }]); if (intialRender) { setIntialRender(false); } } } else { setTage([...tage, { name: el.innerHTML }]); if (intialRender) { setIntialRender(false); } } .... } //use effect function to if user unselect all tags after selctions useEffect(() => { if (tage.length === 0 && !intialRender) { //call parent function and set empty param to true. handleSelectOption(`question${id}`, "", true); } }, [tage]);
step2(parent component):
const [compareTagTitle, setCompareTagTitle] = useState([]); function handleSelectOption(title, item, empty = false) { if (empty) { const filter = compareTagTitle.filter( (value) => value.toString() !== title.toString() ) setCompareTagTitle(filter); setCounter(--counter); } else { if (!compareTagTitle.includes(title)) { setCompareTagTitle([...compareTagTitle, title]); setCounter(++counter); } } }