1

This is a simple todo list app. I'm using a ternary condition in order to update a child component (third line). once the user clicks on the second button (last button), a function in the parent component will be called (passed as a prop property) and update that the task is completed by updating the isCompleted bolead (another click will reverse the decision). However, although the object is being updated with the property, the className will not update. What could be the problem and/or solution? Could it be because the child component is not being rerendered after the update? thanks in advance. This is the part being returned from the child component:

GoalsList.map((item:IGoal)=>{
                          return  <div className='goal-content' key={item.id}>
                            <span className={item.isCompleted ?  'linethrough-true':''}>{`${item.isCompleted}  ${item.goal} to be completed in ${item.deadline} days.`} </span>
                            <span className='buttons-container'>
                            <button onClick={()=>{ 
                                deleteGoal(item.id);
                              }}> <TfiTrash className='icon icon-trash'/></button>
                              <button onClick={()=>{ 
                                completeGoal(item.id);}}><TfiCheck className='icon icon-check'/></button>
                            </span>
                          
                            </div>
                     })

This is the function handling the click at the parent component:

 const completeGoal=(goalCompleted:string):void=>{
        let newGoalsList=GoalsList; 
        newGoalsList.forEach((goal)=>{
        if (goalCompleted==goal.id)
          {
            if (goal.isCompleted==false)
              goal.isCompleted=true;
            else
              goal.isCompleted=false;
          }
          
      }
        );

        setGoalsList(newGoalsList);
        
  }

I wish that the goal property which is shown at the span which contains the className, will be affected by the className update and show a line through each time the isCompleted property is updated to be true.

samnoon
  • 1,340
  • 2
  • 13
  • 23
  • Can you edit the question with a valid markdown please ? The code part is truncated. Can you give us all the code of the component please ? – Raphael Escrig Nov 22 '22 at 14:00

1 Answers1

1

First of all you are mutating the react state.

        let newGoalsList=GoalsList; 

so avoid that first. the best way to avoid that is avoiding use of forEach and instead replace with map and add the logic while iterating just make sure you return a new goal after updating the isCompleted field. some something like this.

 const newGoalsList = GoalsList.map((goal) => {
   if(goal.id === goalCompleted){
     return {...goal, isCompleted: !goal.isCompleted}
   } else {
      return {...goal}
   }
});

Now you can set your set your state.

setGoalsList(newGoalsList);

Seeta Ram Yadav
  • 847
  • 9
  • 16