How to call a function multiple times without breaking at the first execution

Viewed 57

I have a function that changes the status of sub-tasks to true <-> false. On clicking the Main task, its child tasks status should turn true. When I'm running this function in a loop it breaks after the first iteration. How can I change the status of every subtask with status false.

my function is

const changeSubtaskStatus = id => {
       axios.patch(`/subtaskStatus/${id}`)
        .then(res=>{
       setSubTodos([...subTodos].map(ST=>{
                if(ST.id===id){
                     return{
                         ...ST,
                         status: !ST.status
                     }
                }else{
                    return ST;
                }
           }));
        }).catch(err=>console.log(err.message))
   }

And my EventListener is here

const onTaskCheck = id => e =>{
       changeTaskStatus(id);
        const subTasks = subTodos.filter(ST=>ST.taskId===id);
       subTasks.map(ST=>{
           if(ST.status===false){
               changeSubtaskStatus(ST.id);
           }
       }) 
   }

The changeSubtaskStatus works for the first object of the subTasks array and breaks. Please let me know my mistake here. Thanks in advance

1 Answers

When you enqueue multiple state updates in a loop like this then you should really use a functional state update so each update uses the previous state and not the state from the render cycle the callback was created in. The issue is a javascript enclosure of the state from the render cycle the callback is invoked in.

const changeSubtaskStatus = (id) => {
  axios
    .patch(`/subtaskStatus/${id}`)
    .then((res) => {
      setSubTodos((subTodos) =>    // <-- previous state
        subTodos.map((ST) =>       // <-- shallow copy array
          ST.id === id
            ? {
                ...ST,             // <-- shallow copy ST object
                status: !ST.status // <-- update property
              }
            : ST
        )
      );
    })
    .catch((err) => console.log(err.message));
};
Related