Search code examples
reactjsimmutabilityuse-stateusecallback

Change React state in immutable way


I have a state which consists of array of Exam objects one of parameters of it (tasks) is array of objects too. I need to change parameter (status) of one item of parameter array (tasks) in one object (exam) in immutable way. Would appreciate you help.

const changeTaskStatus = useCallback((id) =>{
  setExams(prev => prev.map((exam) =>{
    if (exam.tasks.find(task => task.id === id)) {
      const examCopy = {...exam};
      examCopy.tasks.map(task => {
        if (task.id === id) {
          const taskCopy = {...task};
          task.status = true;
          return taskCopy
        } else {
          return task
        }
      })
      return examCopy;
    } else {
      return exam
    }
  }))
}, [setExams])

Solution

  • If you are looking to update status of all the tasks which matches an id, then here is a solution:

    const update = () => {
      const taskIdToUpdate = 2;
      setData(
        data.map((exam) => ({
          ...exam,
          tasks: exam.tasks.map((task) => {
            if (task.taskId === taskIdToUpdate)
              return { ...task, status: !task.status };
            return task;
          })
        }))
      );
    };
    

    Full sandbox - https://codesandbox.io/s/cranky-water-0qhzh0?file=/src/App.js:432-742