I have this example code. I have a state urls which I create using useState hook. I have initialized urls state to empty array. I have another array arr. For each item in arr, I am pushing that item to urls state. When I render contents of urls, only last item pushed is displayed. It seems while updating urls, only last update is taking effect. What could be wrong?
function Hi() {
const [urls, setUrls] = useState([]);
let arr = ["hi", "hello"];
React.useEffect(() => {
arr.forEach(item => {
let url_list = [...urls];
url_list.push(item);
setUrls(url_list)
})
}, []);
return (
<div>
{urls.map(item => (
<Text>{item}</Text>
))}
</div>
)
}
CodePudding user response:
You're updating the state in each interaction of the array.
The problem here is that setState is asynchronous (read), i.e the update doesn't happen instantly. In other words, when you do let url_list = [...urls], on the second and last iteraction, urls is still [], so that's why you're only getting "hello" into it.
You have 2 main approachs in this case:
1. Update the state after you've mapped the entire array.
React.useEffect(() => {
let url_list = [...urls]
arr.forEach(item => {
url_list.push(item);
})
setUrls(url_list)
}, []);
2. Since setState returns the previous state (read), you can do something like this:
React.useEffect(() => {
arr.forEach(item => {
let url_list = [...urls];
url_list.push(item);
setUrls(prevUrls => ([...prevUrls, ...url_list]))
})
}, []);
CodePudding user response:
You are defining url_list inside forEach. This is reset the values inside url_list on each iterations. Declare url_list outside of forEach and it should be working
