0

I am making a user interface to create a quiz. Users can add questions, and within each question they can add/remove choices for the question. Quiz game

I have a component called CreateQuizPage, which manages state. The questions are stored in "data" (I'm using the useState() hook) as [{questionText: "Here is my question", "choices: ["choice A...","choice B", ...]}, ...]

The question and choices are rendered in my component CreateQuestionPanel

On the CreateQuizPage level I define "addChoiceHandler(idx)" (Where idx is the index of the question for which to add a choice):

const addChoiceHandler = (idx) => {
    setData(prev => [...prev.slice(0, idx), { ...prev[idx], choices: prev[idx].choices.concat([""]) }, ...prev.slice(idx + 1)])
}

This function is passed down to the CreateQuestionPanel level, where it is bound to onClick for the "Add choice" button.

<Button basic compact onClick={() => addChoiceHandler(id)}>Add</Button>

Also on the CreateQuestionPanel level, I render choices for the question:

{
                    choices.map((item, choiceIdx) => {
                        return (
                            <Form.Field key={choiceIdx} >
                                <input
                                    value={item}
                                    name={choiceIdx}
                                    onChange={e => onChoiceTextChange(id, choiceIdx, e.target.value)}
                                    placeholder="Enter choice..."
                                />
                            </Form.Field>
                        )
                    })
                }

When I click the add choice button in strict mode, the useState hook (setData) fires twice, rendering two choices on click. I read that useState hooks fire twice in strict mode to detect side effects. Does that mean I am using state incorrectly? If I turn strict mode off it works correctly - however I want to make sure I am properly modifying state.

Instead of adding an element to the choices array within the useState hook, should I construct an array with an extra item on the panel level and pass it to useData?

Radoradek
  • 93
  • 1
  • 5
  • Hey Radoradek, you check this: https://stackoverflow.com/questions/60825649/why-my-simple-react-component-print-console-twice/60825885#60825885 – Yash Joshi Oct 15 '20 at 15:39
  • I know that turning off Strict Mode will make this work, however, since the whole point of StrictMode double firing useState is to detect side effects, the fact that it creates two choices on click makes me think I am modifying state incorrectly – Radoradek Oct 15 '20 at 15:44

0 Answers0