1

I need to push items to my array, but when I console.log this array, it says 'undefined' for the specific value. I'm trying btw to fetch data from firebase storage. How do I correctly add items to an Array

Here is my code:

const [imagelinks, setImagelinks] = React.useState(['']);
const myFunction = () =>{
  await storage()
      .ref(`${_userid}`)
      .list()
      .then(result => {
        result.items.forEach(async ref => {
          await storage()
            .ref(ref.fullPath)
            .getDownloadURL()
            .then(url => {
              //get url
              setImagelinks([...imagelinks, url]);
              console.log('Links: ' + url);
            });
        });
       //there it says undefined when logging...
       console.log(imagelinks[0])
      });
}

Edit: can I use following?

const imagelinks = [];

//instead of 
const [imagelinks, setImagelinks] = useState([]);

2 Answers 2

1

Updating state is an asynchronous task. A re-render of the component is required in order to have the updated value. To be sure, add your console outside of myFunction, below the state definition for example:

const [imagelinks, setImagelinks] = React.useState(['']);
console.log(imagelinks)

If you wanna use the result to do some logic (an API call for example), you can use the useEffect hook, like this for example:

useEffect(()=>{

  if(imagelinks.length>0){
    // do your things, except do not call setImagelinks in here to avoid having a loop because imagelinks is in the dependencies  array of useEffect.
  }

},[imagelinks])
Sign up to request clarification or add additional context in comments.

8 Comments

Yeah thanks, it console logging content from that array. But how can I use it? Because I normally call a nother function after "console.log.(imagelinks[0])" where I want to use that Array. I want to use that Array in an API call
@DevChris I edited my answer. Take a look please.
useEffect works just keep in mind that useEffect will be triggered any time imageLinks changes even if you change it from somewhere outside of your api calls chain, so compare the two approaches and use the one that suits your app.
Got it, thanks. I removed the result.items.forEachLoop.... and made another loop function but with const url = await result.items[i].getDownloadURL(); setImagelinks(prevState => { return [...prevState, url]; }); and it worked for me
Glad it di work, and thanks for letting us know. Cheers!
|
0

As the previous answer mentioned, you can't access the new state in the same scope after setting it as it will still have the old value for that specific scope.

If you really need to store and access some value in the same scope you can use useRef hook or you can store the value in a variable in that scope.

Here is an example, but keep in mind that changing the referenced value will not trigger a re-render so this will not replace your useState.

variable example:

let imageLinksArray=[...imagelinks, url] //add this in your function
console.log(imageLinksArray) //you can pass this to the next function

useRef example:

const imagelinksRef = useRef() //add this on top after your useState
...
imageLinksRef.current=[...imagelinks, url] //add this in your function
console.log(imageLinksRef.current) //this will give you the result you're expecting

you can also check out this npm package that let's you access the new state through a ref directly after setting it (if you really need to) https://www.npmjs.com/package/react-usestateref

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.