I am trying to do a list with a checkbox in front of it using reactJS. It is checking all the checkboxes when you click on a single checkbox, while it was suppose to just check the single checkbox that was clicked. How do I fix it?
const checkHandler = () => {
if (checked) {
setChecked(false);
}
if (!checked) {
setChecked(true);
}
};
return (
<ul>
{props.taskInputs.map((e) => (
<li key={e.id}>
{e.id && !checked && (
<ImCheckboxChecked className="checkbox" onClick={checkHandler} />
)}
{e.id && checked && (
<ImCheckboxUnchecked className="checkbox" onClick={checkHandler} />
)}
<span
// className='tasks'
className={checked ? "tasks" : "tasksDone"}
>
{e.taskInput}
</span>
<LuEdit
className="edit-icon"
onClick={() => props.editButtonHandler(e.id, e.taskInput)}
/>
<BsTrash
className="delete-icon"
onClick={() => props.removeButtonHandler(e.id)}
/>
</li>
))}
</ul>
)
3
Answers
It is because you are using the same state variable "checked" for all the checkboxes. You need to have a separate one for each checkbox.
The problem here is that all the checkboxes share to the same
checked
state variable.you can create a copy of
taskInputs
in the child component adding for each object a propertyisChecked
equal tofalse
and store them in a local statetaskInputsWithCheck
:then use this function when you click to toggle an input:
don’t forget to map through
taskInputsWithCheck
inside your JSX instead ofprops.taskInputs
and to usee.isChecked
instead ofchecked
stateone other solution is to add
isChecked
property directly to each object oftaskInputs
, then from the child component you use it and when you click to check/uncheck it from the child component, you have to updatetaskInputs
state in the parent component.to do so, you can follow the same logic, create the function in the parent component and pass it to child as
props
.As bored-coder stated, you need to track the state of each of your checkboxes individually.
That doesn’t mean you need N
useState
s, you could use aRecord
to keep track of all the states using a singleuseState
.