I have a series of checkboxes that need to change their UI when they are clicked. For example, if the first checkbox is clicked, it should change color independently from the others.
This is my current work, but it works like a radio button because only one checkbox is checked at a time.
function RecordGame() {
const [checkedStatus, setCheckedStatus] = useState(members.map(() => false))
const handleSetChecked = async (index) => {
let newState = members.map(() => false)
console.log(newState)
newState[index] = true
setCheckedStatus(newState)
}
const playerCheckboxes = members.map((player, index) => {
return (
<div key={index} className="flex gap-2">
<label htmlFor={player.name}>
<Field
checked
type="checkbox"
onClick={() => handleSetChecked(index)}
id={player.name}
name="players"
value={player.name}
/>
<span
// Change the checkbox UI based on the checkedStatus
className={`${checkedStatus[index] ? 'bg-quad text-primary' : 'bg-transparent'}`}
>
{player.name}
</span>
</label>
</div>
)
})
return( {playerCheckboxes} }
CodePudding user response:
The issue is handleSetChecked
is called, this below code line always resets the checkedStatus
to unchecked
for all items in the array.
let newState = members.map(() => false)
Than this line newState[index] = true
in the same function causing the checkbox to behave as radio
button, since for a particular index, it is always setting the status as checked
.
To fix the issue, you need to update handleSetChecked
function, such that it should not reset the checkedStatus
and take care of the previous value for the same index to handle the check and uncheck state for the checkbox.
const handleSetChecked = async (index) => {
let newState = [...checkedStatus] // make a copy of the current state of the checkedStatus
newState[index] = !checkedStatus[index] // update the relevant index based on the previous state. If its checked, uncheck it and vice versa.
setCheckedStatus(newState)
}