I have an object employees that gets updated from user input through setEmployees() inside a function. I don't understand why for loop does not work but map() works to update the value on the webpage. I am not sure if this is react thing or useState() thing or maybe something else that I missed or did not know. Any idea? Thank you.
The employee object that gets updates from useState hook:
const [employees, setEmployees] = useState([
{
id: 0,
name: "Jason",
role: "Engineer",
img: 'https://images.pexels.com/photos/2598024/pexels-photo-2598024.jpeg'
},
{
id: 1,
name: "Abby",
role: "Manager",
img: 'https://images.pexels.com/photos/2598024/pexels-photo-2598024.jpeg'
}
]);
The case where I use for loop but it does not work:
function updateEmployee(id, newName, newRole) {
// Using for loop to update values
const updatedEmployees = employees
for (let i of updatedEmployees) {
if (i.id == id) {
i.name = newName
i.role = newRole
}
}
console.log(updatedEmployees) // updatedEmployees has been successfully updated
setEmployees(updatedEmployees) // object `employees` values have been updated but the update does not show on the webpage
}
The case where I use map() and it works:
function updateEmployee(id, newName, newRole) {
// Using map() to update values
const updatedEmployees = employees.map((employee) => {
if (id == employee.id) {
return {...employee, name: newName, role: newRole}
}
return employee
})
setEmployees(updatedEmployees) // object `employees` values have been updated and also update the values shown on the webpage
}
setEmployeesis auseStatehook, as default React does a shallow compare, if you update an object it will be the same instance, that's why map works because you are creating a new instance. You could do ->setEmployees([...employees]),updatedEmployee. It shouldn't be the same as the original one, right?const updatedEmployees = employeesyour not actually creating a newobject, but just creating a reference to the existing one. When you usedmap, your actually creating a new array, and mapping the values into it. To makeupdateEmployeesa new array, you could also do ->const updatedEmployees = [...employees].. eg..let a = [1,2,3]; let b = [...a]; console.log(a === b);will return false as expected.