Have a Todo App.
Whenever i will click on check it should only trigger handleCheck() for that particular element of Div(Array Elements)
It is triggering handleCheck() in all the div(Array Elements).
const todoData = [
{id:0,todoname:"Study",todotoday:"Completing CSS today"},
{id:1,todoname:"Coding",todotoday:"Leetcode 2 Problems"}
];
const [myArray,setmyArray] = useState(todoData);
const [isChecked, setIsChecked] = useState();
const handleCheck = (id) =>{
console.log(id);
setIsChecked(current => !current);
}
return (
<div className="todomain">
{
myArray.map((obj)=>{
return ( <div className="todobox" key={obj.id} style={{opacity:isChecked ? 0 : ''}}>
<div className="checkcont">
<img src={check} alt="Check" className='chkbtn btn' onClick={() => handleCheck(obj.id)}/>
</div>
<h2 className="head" >Todo: {obj.todoname}</h2>
<h3 className="todocont">{obj.todotoday}</h3>
<div className="todoboxbtn">
<TodoIcon />
</div>
</div> )
})
}
</div>
)
2
Answers
Because there’s a difference between "one thing" and "many things".
This state represents many things (an array):
But this state represents one thing (a single value):
So, when
isChecked
istrue
, which element ofmyArray
does it apply to? Currently your options are "all of them" or "none of them".Instead of just storing a boolean value, perhaps you meant to store the
id
value? For example:Then
checkedItem
would contain theid
of the one "item" which is currently checked. You’d then compare thatid
in the code to conditionally style your elements:Alternatively, if you want to track "checked items" as "many things" then that would be an array. For example:
Checking/unchecking items would be a matter of adding/removing items in that array. For example:
And the condition in the JSX markup would be checking if that array contains the
obj.id
value (rather than is theobj.id
value). For example:In order to make this code work properly you should add
isChecked
property to your data and modify the way you update your state.You final code will look like this: