Reputation: 155
I want to transfer data in an array A into a object B, so i doing something like [array].forEach(e => setB({...B, e})), but it seems like when traversing on later elements, former actions have been "forgotten", how should i achieve my goal?
Prototype should looks like this:
import React from "react"
import {Map} from "immutable"
export default function App() {
const [arrayA, setA] = React.useState([1, 2]);
const [objB, setB] = React.useState(Map({}));
React.useEffect(() => {
arrayA.forEach(num => {
setB(objB.set(num, num*num));
})
}, [])
return (<div>null</div>)
}
Thanks in advance!
Upvotes: 3
Views: 10615
Reputation: 202638
You are correct. With a regular value state update in a loop each subsequent enqueued update overwrites the previous update, so the last update is the one used for the next render cycle.
Normally you would use a functional state update to update from the previous state, not the state from the previous render cycle. In this case it makes more sense to map the arrayA
state to an array of key-value pairs and do a single update for the objB
state.
React.useEffect(() => {
setB(Map(arrayA.map(num => [num, num * num]));
}, []);
Upvotes: 3
Reputation: 6582
You're getting stale data
and you should use setState callback
like this:
export default function App() {
const [arrayA, setA] = React.useState([1, 2]);
const [objB, setB] = React.useState(Map({}));
React.useEffect(() => {
arrayA.forEach((num) => {
setB(oldValue => oldValue.set(num, num * num));
});
}, []);
return <div>null</div>;
}
Upvotes: 1