Home > Mobile >  ReactJS: The last radio button value cannot be sent
ReactJS: The last radio button value cannot be sent

Time:05-12

I try to create a quiz app in ReactJS. I injected a form in slick-carousel. Every slider has only one question with radio buttons.

return (
    <React.Fragment>
          <Slider {...settings} ref={sliderRef}>
                   {data.map((question, index) => (
                     <FormGroup inline className="form-group-center">
                     {
                       [0, 1, 2].map((i) => (
                              <Label check className="me-md-5">
                                   <Input type="radio"
                                          id={question.choices[i]}
                                          name={question.id}
                                          onClick={e => {handleRadioClick(e)}}
                                          value={question.choices[i]}/>
                                   {question.choices[i]}
                              </Label>
                        ))
                      }
                      </FormGroup>
                   ))}
          </Slider>
    </React.Fragment>
)

When the user clicks on a radio button, the answer is set and the next question appears automatically in the new slider card.

const [answers, setAnswers] = useState([]);

const handleRadioClick = (event, index) => {
        const name = event.target.name;
        const value = event.target.value;
        const lastObj = Object.values(data)[Object.values(data).length - 1].id;

        // If the question is the last one, post all answers in an API request. 
        if (lastObj == name) {
            console.log(answers) // Does not show the last answer at first view
            handleSubmit(); // Post API request
        }

        setAnswers(values => ({...values, [name]: value}))

        // When user clicks on a radio button next slider will appear. It runs slickNext();
        next();
}

All of the answers are sent successfully in the API request except the last one.

Once I want to console.log(answers) in the if (lastObj == name) block, the answer of the last question isn't shown in the first radio button click.

However, when I change the value of the radio button by clicking on another radio button, the first clicked value is shown. In other words, the selected answer of the last question can only be shown with the second click.

How can I achieve to send all answers on the first try?

CodePudding user response:

The problem is that you called the function handleSubmit before adding the last answer in your state, the solution is to add the answer before calling the function handleSubmit and don't forget to add the parameter answers to the function handleSubmit because setState is asynchronous, you may not get the latest version of the state.

const [answers, setAnswers] = useState([]);

const handleRadioClick = (event, index) => {
        const name = event.target.name;
        const value = event.target.value;
        const lastObj = Object.values(data)[Object.values(data).length - 1].id;
            
        const answersObject = {...answers, [name]: value} //<== do this first

        // If the question is the last one, post all answers in an API request. 
        if (lastObj == name) {
            console.log(answersObject) // Does not show the last answer at first view
            handleSubmit(answersObject); // Post API request
        }

        setAnswers(answersObject)

        // When user clicks on a radio button next slider will appear. It runs slickNext();
        next();
}

CodePudding user response:

May be it is because

const lastObj = Object.values(data)[Object.values(data).length - 1].id;

seems to return an id.

So the condition might try to compare an id with a name.

I would suggest to console.log(lastObj) to see what lastObj contains.

  • Related