Home > Enterprise >  why is the useState hook not setting the value until the page is reloaded?
why is the useState hook not setting the value until the page is reloaded?

Time:03-30

I'm fetching data from a local server, I want to put the response into images so I can render those urls afterwards

const [images, setImages] = useState([])

useFocusEffect(
  React.useCallback(()=>{
  let id = '62432174021cfe441eb49bf7'

  findImages(id)
  .then(res=>{
     console.log(res.content)
     setImages(res.content)          
     console.log(images)          
  })
 },[])

)//useEffect

you see that console.log(res.content) ? it shows in console the following:

Array [
  Object {
    "__v": 0,
    "_id": "6243499ae6b17dc7de44fb0c",
    "chapterid": "62432174021cfe441eb49bf7",
    "url": "https://firebasestorage...",
  },
  Object {
    "__v": 0,
    "_id": "624349b0e6b17dc7de44fb0e",
    "chapterid": "62432174021cfe441eb49bf7",
    "url": "https://firebasestorage...",
  },
  Object {
    "__v": 0,
    "_id": "624349b7e6b17dc7de44fb10",
    "chapterid": "62432174021cfe441eb49bf7",
    "url": "https://firebasestorage...",
  },
  Object {
    "__v": 0,
    "_id": "624349bde6b17dc7de44fb12",
    "chapterid": "62432174021cfe441eb49bf7",
    "url": "https://firebasestorage...",
  },
]

And you see that console.log(images) ? it's placed 2 lines after and it shows in console the following: Array [], So I'm getting a proper response from the server but when I try to put it into the useState variable it doesn't work, the funny thing is that when I Ctrl S the project then console.log(images) gets the same display in the console as console.log(res.content), which is what I want to happen without having to save the project.

I need that image to set the res.content from the start, I watched this video https://www.youtube.com/watch?v=HvM9Ob4CHa0 the boy is doing the same as me but it works for him, look in the min 1:45, line: 30, I don't know what's going on.

this is an interesting thread that I found Why is useState() not setting the default value? but I dont't think it's the same as my scenario, I think.

CodePudding user response:

The setState function of useState is async. Logging the state right after setting it, won't show the value you have just set.

However, it is guaranteed by the framework that the new value will be available in the next render cycle.

You can test this by logging the state images outside of the useFocusEffect.

const [images, setImages] = useState([])

useFocusEffect(
  React.useCallback(()=>{
  let id = '62432174021cfe441eb49bf7'

  findImages(id)
  .then(res=>{
     console.log(res.content)
     setImages(res.content)                 
  })
 },[])

console.log(images) 

You will notie two log messages. One with an empty array. After the state changes via setImages, you will see a second console.log due to a rerender. This time with the previously set value.

  • Related