I am trying to make a simple task manager app and I want to implement react memo in TaskRow (task item) but when I click the checkbox to finish the task, the component properties are the same and I cannot compare them and all tasks are re-rendered again, any suggestions? Thanks
Sand Box: https://codesandbox.io/s/interesting-tharp-ziwe3?file=/src/components/Tasks/Tasks.jsx
Tasks Component
import React, { useState, useEffect, useCallback } from 'react'
import TaskRow from "../TaskRow";
function Tasks(props) {
const [taskItems, setTaskItems] = useState([])
useEffect(() => {
setTaskItems(JSON.parse(localStorage.getItem('tasks')) || [])
}, [])
useEffect(() => {
if (!props.newTask) return
newTask({ id: taskItems.length + 1, ...props.newTask })
}, [props.newTask])
const newTask = (task) => {
updateItems([...taskItems, task])
}
const toggleDoneTask = useCallback((id) => {
const taskItemsCopy = [...taskItems]
taskItemsCopy.map((t)=>{
if(t.id === id){
t.done = !t.done
return t
}
return t
})
console.log(taskItemsCopy)
console.log(taskItems)
updateItems(taskItemsCopy)
}, [taskItems])
const updateItems = (tasks) => {
setTaskItems(tasks)
localStorage.setItem('tasks', JSON.stringify(tasks))
}
return (
<React.Fragment>
<h1>learning react </h1>
<table>
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Done</th>
</tr>
</thead>
<tbody>
{
props.show ? taskItems.map((task, i) =>
<TaskRow
task={task}
key={task.id}
toggleDoneTask={()=>toggleDoneTask(task.id)}>
</TaskRow>)
:
taskItems.filter((task) => !task.done)
.map((task) =>
<TaskRow
show={props.show}
task={task}
key={task.id}
toggleDoneTask={()=>toggleDoneTask(task.id)}></TaskRow>
)
}
</tbody>
</table>
</React.Fragment>
)
}
export default Tasks
Item task (TaskRow component)
import React, { memo } from 'react'
function TaskRow(props) {
return (<React.Fragment>
{console.log('render', props.task)}
<Tr show={props.show} taskDone={props.task.done}>
<td>
{props.task.title}
</td>
<td>
{props.task.description}
</td>
<td>
<input type="checkbox"
checked={props.task.done}
onChange={props.toggleDoneTask}
/>
</td>
</Tr>
</React.Fragment>)
}
export default memo(TaskRow, (prev,next)=>{
console.log('prev props', prev.task)
console.log('next props', next.task)
})