0

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> ); } 

2 Answers 2

1

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> ); } 
Sign up to request clarification or add additional context in comments.

2 Comments

It works, but I heard spread operator does shallow copy, so didn't want to use it. Wouldn't arr[i].added perform the operation on the users instead of arr?
Don't mutate state directly.
0

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 }) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.