So me and my colleague are writing a React/ServiceNow project for internal use of our company. I'm using the reducer hook to manage state throughout the app. I've got the following structure App components, which calls the API (array with questions and their respective answers). This info is passed down to TrainingMode and that returns
return
(
<QuizContext.Provider value={{ state, dispatch }}>
<div className='container'>
<Progress />
{'Training'}
<Question />
{renderError()}
<Answers />
<button className='btn btn-primary' onClick={next}>
Confirm and Continue
</button>
</div>
</QuizContext.Provider>
);
Answers:
function Answers() {
const { state, dispatch } = useContext(QuizContext);
const { currentAnswer, currentQuestion, questions } = state;
const question = questions[currentQuestion].question;
const answers = questions[currentQuestion].answers;
console.log('curr ans is ' + question);
console.log(answers);
let firstLetter = 65;
const ans = answers.map((el) => {
return (
<Answer
key={el.sys_id}
letter={(firstLetter++).toString()}
answer={el.answer_text}
answer_sysId={el.sys_id}
selected={currentAnswer === el.sys_id}
dispatch={dispatch}
/>
);
});
return <>{ans}</>;
Individual Answer:
function Answer(props) {
let classes = ['answer'];
const handleClick = (e) => {
props.dispatch({
type: SET_CURRENT_ANSWER,
currentAnswer: props.answer_sysId
});
props.dispatch({ type: SET_ERROR, error: '' });
};
if (props.selected) {
classes.push('selected');
}
return (
<button
value={props.answer}
className={classes.join(' ')}
onClick={handleClick}
>
<span>{String.fromCharCode(props.letter)}.</span> {props.answer}
</button>
);
}
And last, the reducer:
function quizReducer(state, action) {
switch (action.type) {
case SET_CURRENT_ANSWER:
console.log(action);
state.currentAnswer.push(action.currentAnswer);
return {
...state
// currentAnswer: action.currentAnswer
};
case SET_CURRENT_QUESTION:
return {
...state,
currentQuestion: action.currentQuestion
};
case SET_ERROR:
return {
...state,
error: action.error
};
case SET_SHOW_RESULTS:
return {
...state,
showResults: action.showResults
};
case SET_ANSWERS:
return {
...state,
answers: action.answers
};
case ADD_CORRECT:
return {
...state,
correct: action.correct
};
case RESET_QUIZ:
return {
...state,
answers: [],
currentQuestion: 0,
currentAnswer: '',
showResults: false,
error: '',
correct: 0
};
default:
return state;
}
I want to click on each individual answer and push it to the currentAnswer array (so it works for both single and multiple choice questions). It kind of works, it pushes the first answer I click just once, however when I click on other answers, it pushes them twice. When I comment out the Strict mode tag, everything works fine, however I doubt that's the best solution. console log
I've read though some articles but can't seem to fix this.