Skip to content
Advertisement

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

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

Advertisement

Answer

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));
};
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement