0

This is all new to me and I'm still learning. I'm trying to create a form quiz, including an input title, an input question, and a few input answers (with a checkbox).

A button '+add answer' is created to be able to add new inputs 'answer' in the quiz.

I created an array of objects and now I need to be able to push into the array the new inputs when I click on the button '+add answer'. I know I have to use the .push() method, but the typescript makes it harder for me to know how to do that.

Here is the full code:

function QuizForm() {

    const [inputTitle, setInputTitle] = useState<string>('');
    const [inputQuestion, setInputQuestion] = useState<string>('');
    const [answers, setAnswers] = useState<{
        correct: boolean,
        label: string,
        value: string,
        id: number
    }[]>([
        {
            correct: false,
            label: "Answer 1 ...",
            value: "",
            id: 0
        },

        {
            correct: false,
            label: "Answer 2 ...",
            value: "",
            id: 1
        }

    ]);



        return (
        <div className="container-fluid w-75">
            <h2 className="row my-3 justify-content-center title1">Quiz</h2>
            <div>

                <div className="row justify-content-center">
                    <Form.Control className="formbg form3" type="title" name="title"
                                  placeholder={'Quiz title ...'}
                                  onChange={(event => setInputTitle(event.target.value))}/>
                </div>

                <div className="row my-2 justify-content-center">
                    <Form.Control className="formbg form3" type="text" name="question" placeholder={'Question ...'}
                                  onChange={(event => setInputQuestion(event.target.value))}/>
                </div>

                {
                    answers.map((item) => {
                        return (
                            <>
                                <div className="row mt-4 justify-content-center">
                                    <Form.Control className="formbg form3" type="text" name="text" placeholder={item.label}/>
                                </div>

                                <div className="row">
                                    <input type="checkbox" id="link1"/>
                                    <label htmlFor="link1" className="my-2">Good answer</label>
                                </div>
                            </>
                        )
                    })
                }




                <div className="my-4 line2"/>
            </div>

            <div className="row">
                <Button
                    className="addbutton border-0">+ add answer
                </Button>

            </div>
            <div className="row my-5 justify-content-center">
                <Button className="registerbutton" block size="lg" type="submit"
                        onClick={() => console.log({
                            inputTitle,
                            inputQuestion,
                        })}>Save</Button>
            </div>
        </div>
    )

}

export default QuizForm;

Thanks so much!

2
  • <Button onClick={() => setAnswers([...answers, newAnswer])} className="addbutton border-0">+ add answer </Button> should do the job. Read more about useState hook and destructuring Commented Apr 9, 2021 at 14:18
  • Does this answer your question? React Typescript how to setState Commented Apr 9, 2021 at 14:23

2 Answers 2

0

The key is that React state should be treated as immutable. So clicking the add answer button should invoke setAnswers passing in a new array of answers, which is constructed from the existing array, and appending the new answer.

<Button
  className="addbutton border-0"
  onClick={(ev) => {
    const id = answers.length;
    const newAnswer = {
       correct: false,
       label: `Answer ${id + 1} ...`,
       value: "",
       id,
    };
    setAnswers([...answers, newAnswer])
  }}
>+ add answer
</Button>

Array.prototype.push() is not suitable here because that mutates the existing array. [...answers, newAnswers] returns a new list which is a copy of the existing answers, along with newAnswers as the last element.

Sign up to request clarification or add additional context in comments.

1 Comment

This worked!! Thank you so much for the help! :-)
0

Actually removing all my previous information as the answer can be found here.

React Typescript how to setState

5 Comments

setAnswers is defined on Line 5. The OP's question seems to be how to invoke setAnswers to update the answers' state.
Sure sorry didnt see that was reading too quickly XD
I didn't know if I had to create a new function for that since I thought I could directly to that into my array
Not downvoting, but this should be a comment not an answer. Also, avoid pasting links unless you copy the important bits from there, because links may die over time
Sure will add the important bits. Thanks for the tip

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.