I'm calling a completeTask function within a todo list
</IconButton>
{task.isComplete ? (
<Button
startIcon={<UndoIcon />}
onClick={() => completeTask(task.id)}
>
Mark as not complete
</Button>
) : (
<Button
startIcon={<CheckIcon />}
onClick={() => completeTask(task.id)}
>
Complete Task
</Button>
)}
However, when I click complete, the json server db updates but the UI doesn't update, until the second click
const completeTask = async (id) => {
const taskToToggle = await fetchTask(id)
const updTask = {...taskToToggle, isComplete: !taskToToggle.isComplete}
const res = await fetch(`http://localhost:8000/tasks/${id}`, {
method: 'PUT',
headers: {
'Content-type' : 'application/json'
},
body: JSON.stringify(updTask)
})
const data = await res.json()
setTasks(
tasks.map((task) =>
task.id===id ? {...task, isComplete:!data.isComplete} :task
)
)
What am I doing wrong, and how can I ensure the UI re-renders after each click?
data is the new value, you don't need use !data.isComplete
. Just update without !
setTasks(
tasks.map((task) =>
task.id===id ? {...task, isComplete:data.isComplete} :task
)
)