Reputation: 935
I am trying to update each element in an array using a for loop
When you click on the 'add all' button, it should start updating each element of the array
The update should happen one after the other, and should be visible in the UI
The array is stored in a useState
hook
However, the array is not updating as expected
Here's the link to the CodeSandBox : https://codesandbox.io/s/heuristic-hooks-z3wq7?file=/src/App.js
export default function App() {
const [users, setUsers] = useState(() => fakeUsers);
function addHandler(id){
let arr = cloneDeep(users);
let i = arr.findIndex((u) => u.id === id);
arr[i].added = true;
setUsers(arr);
};
async function addAll() {
for (let i = 0; i < users.length; i++) {
let id = users[i].id;
await delay(1000);
addHandler(id);
}
}
return (
<div className="App">
<button onClick={addAll}>add all</button>
{users.map((e) => (
<div>
{e.name}-{e.added ? "YES" : "NO"}
</div>
))}
</div>
);
}
Upvotes: 0
Views: 612
Reputation: 832
You are using an out of date version of the user array. when the second user is added it uses a reference of the array where none is added.
You can provide a update function to setState to always use the current reference:
setUsers(users => {
let arr = cloneDeep(users);
let i = arr.findIndex((u) => u.id === id);
arr[i].added = true;
return arr
})
Upvotes: 0
Reputation: 1240
Use spread operator instead of cloneDeep.
Also, not sure why you are setting the initial state using arrow function.
here's the updated code
export default function App() {
const [users, setUsers] = useState(fakeUsers);
function addHandler(id) {
let arr = [...users];
let i = arr.findIndex((u) => u.id === id);
arr[i].added = true;
setUsers(arr);
}
async function addAll() {
for (let i = 0; i < users.length; i++) {
let id = users[i].id;
await delay(1000);
addHandler(id);
}
}
return (
<div className="App">
<button onClick={addAll}>add all</button>
{users.map((e) => (
<div>
{e.name}-{e.added ? "YES" : "NO"}
</div>
))}
</div>
);
}
Upvotes: 1