If we console log your state
after selecting any of the 'Agree' options, your state
looks like this...
{selectedOption: "1"}
...all of your components that you are mapping are rendering the checked box as 'checked', on the condition that...
state.selectedOption == 1
...so it would be expected that all boxes in your form would check. The solution to this is to make the condition unique to each checkbox...
-
I renamed
state
toselections
, as naming it state is confusing, as you have multiple states. -
Secondly, on initialisation of
selections
, it is set to an array equaling the number of questions you have. -
I added
index
as an argument to your map -
Your handleChange function now takes two arguments...
index
-> the index of the form from the mapselection
-> the choice from the form
...copies the original selections
array, and changes the index of the selections
array to the selection
argument we passed. eg. agree on the first form iteration if we passed two questions, it would change the 'selections' state from [], []
to [1], []
- The checked condition now looks to see if the
selections
array matches the number assigned to each selection. - Finally we pass the selection number and the index to handleChange.
The selections now all work independently and logging the selected
state on submit gives us something like this...
{0: 1, 1: 2, 2: 1} 0: 1 1: 2 2: 1
..where the first three questions have been selected Agree, Strongly Agree and Agree (I'd also put strongly agree above agree).
import React, { useState } from "react";
import { v4 as uuidv4 } from "uuid";
export default function Header({ questions }) {
const [question, setQuestion] = useState(questions);
const [selections, setSelections] = useState([Object.keys(questions).map(x => [])]);
const submitHandler = () => {
console.log(selections);
};
const handleChange = (selection, index) => {
let tempState = {...selections}
tempState[index] = selection
setSelections(tempState);
};
return (
<div>
<header>
<h1 className="title">
Personality Identification using Machine Learning
</h1>
<h2 className="description">
Please Answer following 50 Questions to Detect your personality type
</h2>
</header>
<ol className="questions">
{question.map((item, index) => {
return (
<>
<li
key={uuidv4()}
className="question"
name={`question_${question.indexOf(item)}`}
>
<h3>{item.question}</h3>
<form className="choices">
<div>
<label>
<input
type="radio"
name="choice"
value={item.choices[0]}
checked={selections[index] === 1}
onChange={() => handleChange(1, index)}
/>
<span>Agree</span>
</label>
</div>
<div>
<label>
<input
type="radio"
name="choice"
value={item.choices[1]}
checked={selections[index] === 2}
onChange={() => handleChange(2, index)}
/>
<span>Strongly agree</span>
</label>
</div>
<div>
<label>
<input
type="radio"
name="choice"
value={item.choices[2]}
checked={selections[index] === 3}
onChange={() => handleChange(3, index)}
/>
<span>Neutral</span>
</label>
</div>
<div>
<label>
<input
type="radio"
name="choice"
value={item.choices[3]}
checked={selections[index] === 4}
onChange={() => handleChange(4, index)}
/>
<span>Disagree</span>
</label>
</div>
<div>
<label>
<input
type="radio"
name="choice"
value={item.choices[4]}
checked={selections[index] === 5}
onChange={() => handleChange(5, index)}
/>
<span>Strongly Disagree</span>
</label>
</div>
</form>
</li>
<hr />
</>
);
})}
</ol>
<div className="button_container">
<button className="btn" onClick={submitHandler}>
<span>Submit</span>
</button>
</div>
</div>
);
}